diff --git a/CHANGELOG.md b/CHANGELOG.md index dd057c2e..8baf3709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `base_url` and `api_key` are now optional. These can be implicitly set via secrets that follow a naming convention. See the Secrets reference page on the wiki for details. +### Changed + +- Better error messages for manually-specified, non-existent config files. + ### Fixed - Resolved error during exception message formatting that occurred in some cases (#192). diff --git a/src/Recyclarr.Cli/Console/Commands/SyncCommand.cs b/src/Recyclarr.Cli/Console/Commands/SyncCommand.cs index 68dcee95..e7e60e62 100644 --- a/src/Recyclarr.Cli/Console/Commands/SyncCommand.cs +++ b/src/Recyclarr.Cli/Console/Commands/SyncCommand.cs @@ -1,6 +1,5 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.IO.Abstractions; using JetBrains.Annotations; using Recyclarr.Cli.Console.Helpers; using Recyclarr.Cli.Console.Settings; @@ -33,10 +32,9 @@ public class SyncCommand : AsyncCommand [CommandOption("-c|--config")] [Description("One or more YAML configuration files to load & use.")] - [TypeConverter(typeof(FileInfoConverter))] [UsedImplicitly(ImplicitUseKindFlags.Assign)] - public IFileInfo[] ConfigsOption { get; init; } = Array.Empty(); - public IReadOnlyCollection Configs => ConfigsOption; + public string[] ConfigsOption { get; init; } = Array.Empty(); + public IReadOnlyCollection Configs => ConfigsOption; [CommandOption("-p|--preview")] [Description("Perform a dry run: preview the results without syncing.")] diff --git a/src/Recyclarr.Cli/Console/Helpers/FileInfoConverter.cs b/src/Recyclarr.Cli/Console/Helpers/FileInfoConverter.cs deleted file mode 100644 index ed7de039..00000000 --- a/src/Recyclarr.Cli/Console/Helpers/FileInfoConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.ComponentModel; -using System.Globalization; -using System.IO.Abstractions; - -namespace Recyclarr.Cli.Console.Helpers; - -internal class FileInfoConverter : TypeConverter -{ - private readonly IFileSystem _fs; - - public FileInfoConverter(IFileSystem fs) - { - _fs = fs; - } - - public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) - { - // ReSharper disable once InvertIf - if (value is string path) - { - var info = _fs.FileInfo.New(path); - if (!info.Exists) - { - throw new FileNotFoundException("The file does not exist", path); - } - - return info; - } - - return null; - } -} diff --git a/src/Recyclarr.Cli/Console/Settings/ISyncSettings.cs b/src/Recyclarr.Cli/Console/Settings/ISyncSettings.cs index 6aa9cccd..fc37a82f 100644 --- a/src/Recyclarr.Cli/Console/Settings/ISyncSettings.cs +++ b/src/Recyclarr.Cli/Console/Settings/ISyncSettings.cs @@ -1,4 +1,3 @@ -using System.IO.Abstractions; using Recyclarr.TrashLib.Config; namespace Recyclarr.Cli.Console.Settings; @@ -6,7 +5,7 @@ namespace Recyclarr.Cli.Console.Settings; public interface ISyncSettings { SupportedServices? Service { get; } - IReadOnlyCollection Configs { get; } + IReadOnlyCollection Configs { get; } bool Preview { get; } IReadOnlyCollection? Instances { get; } } diff --git a/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs b/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs index 384e6848..ff8f4f71 100644 --- a/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs +++ b/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.IO.Abstractions; using Flurl.Http; using Recyclarr.Cli.Console.Settings; using Recyclarr.TrashLib.Compatibility; @@ -20,6 +21,7 @@ public class SyncProcessor : ISyncProcessor private readonly IConfigurationLoader _configLoader; private readonly SyncPipelineExecutor _pipelines; private readonly ServiceAgnosticCapabilityEnforcer _capabilityEnforcer; + private readonly IFileSystem _fs; public SyncProcessor( IAnsiConsole console, @@ -27,7 +29,8 @@ public class SyncProcessor : ISyncProcessor IConfigurationFinder configFinder, IConfigurationLoader configLoader, SyncPipelineExecutor pipelines, - ServiceAgnosticCapabilityEnforcer capabilityEnforcer) + ServiceAgnosticCapabilityEnforcer capabilityEnforcer, + IFileSystem fs) { _console = console; _log = log; @@ -35,6 +38,7 @@ public class SyncProcessor : ISyncProcessor _configLoader = configLoader; _pipelines = pipelines; _capabilityEnforcer = capabilityEnforcer; + _fs = fs; } public async Task ProcessConfigs(ISyncSettings settings) @@ -42,7 +46,22 @@ public class SyncProcessor : ISyncProcessor bool failureDetected; try { - var configs = _configLoader.LoadMany(_configFinder.GetConfigFiles(settings.Configs)); + var configFiles = settings.Configs + .Select(x => _fs.FileInfo.New(x)) + .ToLookup(x => x.Exists); + + if (configFiles[false].Any()) + { + foreach (var file in configFiles[false]) + { + _log.Error("Manually-specified configuration file does not exist: {File}", file); + } + + _log.Error("Exiting due to non-existent configuration files"); + return ExitStatus.Failed; + } + + var configs = _configLoader.LoadMany(_configFinder.GetConfigFiles(configFiles[true].ToList())); LogInvalidInstances(settings.Instances, configs); @@ -93,6 +112,8 @@ public class SyncProcessor : ISyncProcessor private void HandleException(Exception e) { + _log.Debug(e, "Sync Processor Exception"); + switch (e) { case GitCmdException e2: @@ -105,8 +126,7 @@ public class SyncProcessor : ISyncProcessor break; default: - _log.Error(e, "Exception"); - break; + throw e; } } diff --git a/src/Recyclarr.Cli/Program.cs b/src/Recyclarr.Cli/Program.cs index 0f5a4ded..97b1aca6 100644 --- a/src/Recyclarr.Cli/Program.cs +++ b/src/Recyclarr.Cli/Program.cs @@ -38,7 +38,6 @@ internal static class Program config.Settings.StrictParsing = true; config.SetApplicationName("recyclarr"); - // config.SetApplicationVersion("v1.2.3"); var interceptor = new CliInterceptor(logLevelSwitch, appDataPathProvider); interceptor.OnIntercepted.Subscribe(_ => OnAppInitialized());