diff --git a/CHANGELOG.md b/CHANGELOG.md index 869784e2..272d042e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - When using `sync`, continue processing other instances when there's a failure. +- Regression: Perform Sonarr compatibility checks again (#189). ## [5.0.2] - 2023-06-24 diff --git a/src/Recyclarr.Cli/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs b/src/Recyclarr.Cli/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs index cb8d9d3a..3dcf720a 100644 --- a/src/Recyclarr.Cli/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs +++ b/src/Recyclarr.Cli/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs @@ -12,16 +12,16 @@ namespace Recyclarr.Cli.Pipelines.ReleaseProfile.Api; public class SonarrReleaseProfileCompatibilityHandler : ISonarrReleaseProfileCompatibilityHandler { private readonly ILogger _log; - private readonly ISonarrCapabilityChecker _capabilityChecker; + private readonly ISonarrCapabilityFetcher _capabilityFetcher; private readonly IMapper _mapper; public SonarrReleaseProfileCompatibilityHandler( ILogger log, - ISonarrCapabilityChecker capabilityChecker, + ISonarrCapabilityFetcher capabilityFetcher, IMapper mapper) { _log = log; - _capabilityChecker = capabilityChecker; + _capabilityFetcher = capabilityFetcher; _mapper = mapper; } @@ -29,7 +29,7 @@ public class SonarrReleaseProfileCompatibilityHandler : ISonarrReleaseProfileCom IServiceConfiguration config, SonarrReleaseProfile profile) { - var capabilities = await _capabilityChecker.GetCapabilities(config); + var capabilities = await _capabilityFetcher.GetCapabilities(config); if (capabilities is null) { throw new ServiceIncompatibilityException("Capabilities could not be obtained"); diff --git a/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs b/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs index 5783f9ae..384e6848 100644 --- a/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs +++ b/src/Recyclarr.Cli/Processors/Sync/SyncProcessor.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Flurl.Http; using Recyclarr.Cli.Console.Settings; +using Recyclarr.TrashLib.Compatibility; using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Parsing; using Recyclarr.TrashLib.Config.Services; @@ -18,19 +19,22 @@ public class SyncProcessor : ISyncProcessor private readonly IConfigurationFinder _configFinder; private readonly IConfigurationLoader _configLoader; private readonly SyncPipelineExecutor _pipelines; + private readonly ServiceAgnosticCapabilityEnforcer _capabilityEnforcer; public SyncProcessor( IAnsiConsole console, ILogger log, IConfigurationFinder configFinder, IConfigurationLoader configLoader, - SyncPipelineExecutor pipelines) + SyncPipelineExecutor pipelines, + ServiceAgnosticCapabilityEnforcer capabilityEnforcer) { _console = console; _log = log; _configFinder = configFinder; _configLoader = configLoader; _pipelines = pipelines; + _capabilityEnforcer = capabilityEnforcer; } public async Task ProcessConfigs(ISyncSettings settings) @@ -74,6 +78,7 @@ public class SyncProcessor : ISyncProcessor try { PrintProcessingHeader(config.ServiceType, config); + await _capabilityEnforcer.Check(config); await _pipelines.Process(settings, config); } catch (Exception e) diff --git a/src/Recyclarr.TrashLib/Compatibility/CompatibilityAutofacModule.cs b/src/Recyclarr.TrashLib/Compatibility/CompatibilityAutofacModule.cs index 441dd948..2d638c21 100644 --- a/src/Recyclarr.TrashLib/Compatibility/CompatibilityAutofacModule.cs +++ b/src/Recyclarr.TrashLib/Compatibility/CompatibilityAutofacModule.cs @@ -10,12 +10,14 @@ public class CompatibilityAutofacModule : Module { base.Load(builder); + builder.RegisterType(); + // Sonarr + builder.RegisterType().As(); builder.RegisterType(); - builder.RegisterType().As() - .InstancePerLifetimeScope(); // Radarr - builder.RegisterType().InstancePerLifetimeScope(); + builder.RegisterType().As(); + builder.RegisterType(); } } diff --git a/src/Recyclarr.TrashLib/Compatibility/Radarr/IRadarrCapabilityFetcher.cs b/src/Recyclarr.TrashLib/Compatibility/Radarr/IRadarrCapabilityFetcher.cs new file mode 100644 index 00000000..1638866b --- /dev/null +++ b/src/Recyclarr.TrashLib/Compatibility/Radarr/IRadarrCapabilityFetcher.cs @@ -0,0 +1,8 @@ +using Recyclarr.TrashLib.Config.Services; + +namespace Recyclarr.TrashLib.Compatibility.Radarr; + +public interface IRadarrCapabilityFetcher +{ + Task GetCapabilities(IServiceConfiguration config); +} diff --git a/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityEnforcer.cs b/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityEnforcer.cs new file mode 100644 index 00000000..d6551027 --- /dev/null +++ b/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityEnforcer.cs @@ -0,0 +1,25 @@ +using Recyclarr.TrashLib.Config.Services; +using Recyclarr.TrashLib.ExceptionTypes; + +namespace Recyclarr.TrashLib.Compatibility.Radarr; + +public class RadarrCapabilityEnforcer +{ + private readonly IRadarrCapabilityFetcher _capabilityFetcher; + + public RadarrCapabilityEnforcer(IRadarrCapabilityFetcher capabilityFetcher) + { + _capabilityFetcher = capabilityFetcher; + } + + public async Task Check(RadarrConfiguration config) + { + var capabilities = await _capabilityFetcher.GetCapabilities(config); + if (capabilities is null) + { + throw new ServiceIncompatibilityException("Capabilities could not be obtained"); + } + + // For the future: Add more capability checks here as needed + } +} diff --git a/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityChecker.cs b/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityFetcher.cs similarity index 62% rename from src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityChecker.cs rename to src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityFetcher.cs index 96962b0b..6f91b14e 100644 --- a/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityChecker.cs +++ b/src/Recyclarr.TrashLib/Compatibility/Radarr/RadarrCapabilityFetcher.cs @@ -2,9 +2,9 @@ using Recyclarr.TrashLib.ApiServices.System; namespace Recyclarr.TrashLib.Compatibility.Radarr; -public class RadarrCapabilityChecker : ServiceCapabilityChecker +public class RadarrCapabilityFetcher : ServiceCapabilityFetcher, IRadarrCapabilityFetcher { - public RadarrCapabilityChecker(IServiceInformation info) + public RadarrCapabilityFetcher(IServiceInformation info) : base(info) { } diff --git a/src/Recyclarr.TrashLib/Compatibility/ServiceAgnosticCapabilityEnforcer.cs b/src/Recyclarr.TrashLib/Compatibility/ServiceAgnosticCapabilityEnforcer.cs new file mode 100644 index 00000000..7306fd3e --- /dev/null +++ b/src/Recyclarr.TrashLib/Compatibility/ServiceAgnosticCapabilityEnforcer.cs @@ -0,0 +1,33 @@ +using Recyclarr.TrashLib.Compatibility.Radarr; +using Recyclarr.TrashLib.Compatibility.Sonarr; +using Recyclarr.TrashLib.Config.Services; + +namespace Recyclarr.TrashLib.Compatibility; + +public class ServiceAgnosticCapabilityEnforcer +{ + private readonly SonarrCapabilityEnforcer _sonarrEnforcer; + private readonly RadarrCapabilityEnforcer _radarrEnforcer; + + public ServiceAgnosticCapabilityEnforcer( + SonarrCapabilityEnforcer sonarrEnforcer, + RadarrCapabilityEnforcer radarrEnforcer) + { + _sonarrEnforcer = sonarrEnforcer; + _radarrEnforcer = radarrEnforcer; + } + + public async Task Check(IServiceConfiguration config) + { + switch (config) + { + case SonarrConfiguration c: + await _sonarrEnforcer.Check(c); + break; + + case RadarrConfiguration c: + await _radarrEnforcer.Check(c); + break; + } + } +} diff --git a/src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityChecker.cs b/src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityFetcher.cs similarity index 79% rename from src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityChecker.cs rename to src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityFetcher.cs index 4f9582fd..7b03333a 100644 --- a/src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityChecker.cs +++ b/src/Recyclarr.TrashLib/Compatibility/ServiceCapabilityFetcher.cs @@ -3,11 +3,11 @@ using Recyclarr.TrashLib.Config.Services; namespace Recyclarr.TrashLib.Compatibility; -public abstract class ServiceCapabilityChecker where T : class +public abstract class ServiceCapabilityFetcher where T : class { private readonly IServiceInformation _info; - protected ServiceCapabilityChecker(IServiceInformation info) + protected ServiceCapabilityFetcher(IServiceInformation info) { _info = info; } diff --git a/src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityChecker.cs b/src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityFetcher.cs similarity index 80% rename from src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityChecker.cs rename to src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityFetcher.cs index 3cb5a05c..f5a4bb72 100644 --- a/src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityChecker.cs +++ b/src/Recyclarr.TrashLib/Compatibility/Sonarr/ISonarrCapabilityFetcher.cs @@ -2,7 +2,7 @@ using Recyclarr.TrashLib.Config.Services; namespace Recyclarr.TrashLib.Compatibility.Sonarr; -public interface ISonarrCapabilityChecker +public interface ISonarrCapabilityFetcher { Task GetCapabilities(IServiceConfiguration config); } diff --git a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilities.cs b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilities.cs index e6bc3ac2..e8602c9a 100644 --- a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilities.cs +++ b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilities.cs @@ -1,8 +1,10 @@ namespace Recyclarr.TrashLib.Compatibility.Sonarr; -public record SonarrCapabilities(Version Version) +public record SonarrCapabilities { - public static Version MinimumVersion => new("3.0.4.1098"); + public static Version MinimumVersion { get; } = new("3.0.4.1098"); + + public Version Version { get; init; } = new(); public bool SupportsNamedReleaseProfiles { get; init; } diff --git a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityEnforcer.cs b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityEnforcer.cs index c3a115fa..f84b037f 100644 --- a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityEnforcer.cs +++ b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityEnforcer.cs @@ -6,16 +6,16 @@ namespace Recyclarr.TrashLib.Compatibility.Sonarr; public class SonarrCapabilityEnforcer { - private readonly ISonarrCapabilityChecker _capabilityChecker; + private readonly ISonarrCapabilityFetcher _capabilityFetcher; - public SonarrCapabilityEnforcer(ISonarrCapabilityChecker capabilityChecker) + public SonarrCapabilityEnforcer(ISonarrCapabilityFetcher capabilityFetcher) { - _capabilityChecker = capabilityChecker; + _capabilityFetcher = capabilityFetcher; } public async Task Check(SonarrConfiguration config) { - var capabilities = await _capabilityChecker.GetCapabilities(config); + var capabilities = await _capabilityFetcher.GetCapabilities(config); if (capabilities is null) { throw new ServiceIncompatibilityException("Capabilities could not be obtained"); diff --git a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityChecker.cs b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityFetcher.cs similarity index 69% rename from src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityChecker.cs rename to src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityFetcher.cs index 06fd58bd..fd481c3a 100644 --- a/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityChecker.cs +++ b/src/Recyclarr.TrashLib/Compatibility/Sonarr/SonarrCapabilityFetcher.cs @@ -2,17 +2,19 @@ using Recyclarr.TrashLib.ApiServices.System; namespace Recyclarr.TrashLib.Compatibility.Sonarr; -public class SonarrCapabilityChecker : ServiceCapabilityChecker, ISonarrCapabilityChecker +public class SonarrCapabilityFetcher : ServiceCapabilityFetcher, ISonarrCapabilityFetcher { - public SonarrCapabilityChecker(IServiceInformation info) + public SonarrCapabilityFetcher(IServiceInformation info) : base(info) { } protected override SonarrCapabilities BuildCapabilitiesObject(Version version) { - return new SonarrCapabilities(version) + return new SonarrCapabilities { + Version = version, + SupportsNamedReleaseProfiles = version >= SonarrCapabilities.MinimumVersion, diff --git a/src/tests/Recyclarr.Cli.Tests/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandlerTest.cs b/src/tests/Recyclarr.Cli.Tests/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandlerTest.cs index 911deb61..1a90ee8b 100644 --- a/src/tests/Recyclarr.Cli.Tests/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandlerTest.cs +++ b/src/tests/Recyclarr.Cli.Tests/Pipelines/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandlerTest.cs @@ -28,7 +28,7 @@ public class SonarrReleaseProfileCompatibilityHandlerTest : CliIntegrationFixtur protected override void RegisterTypes(ContainerBuilder builder) { base.RegisterTypes(builder); - builder.RegisterMockFor(); + builder.RegisterMockFor(); } [Test] @@ -59,8 +59,8 @@ public class SonarrReleaseProfileCompatibilityHandlerTest : CliIntegrationFixtur [Test] public async Task Send_v2_to_v1() { - var capabilityChecker = Resolve(); - capabilityChecker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities(new Version()) + var capabilityChecker = Resolve(); + capabilityChecker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities { ArraysNeededForReleaseProfileRequiredAndIgnored = false }); @@ -76,8 +76,8 @@ public class SonarrReleaseProfileCompatibilityHandlerTest : CliIntegrationFixtur [Test] public async Task Send_v2_to_v2() { - var capabilityChecker = Resolve(); - capabilityChecker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities(new Version()) + var capabilityChecker = Resolve(); + capabilityChecker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities { ArraysNeededForReleaseProfileRequiredAndIgnored = true }); diff --git a/src/tests/Recyclarr.TrashLib.Tests/Compatibility/Sonarr/SonarrCapabilityEnforcerTest.cs b/src/tests/Recyclarr.TrashLib.Tests/Compatibility/Sonarr/SonarrCapabilityEnforcerTest.cs index 5738a499..2a76ff70 100644 --- a/src/tests/Recyclarr.TrashLib.Tests/Compatibility/Sonarr/SonarrCapabilityEnforcerTest.cs +++ b/src/tests/Recyclarr.TrashLib.Tests/Compatibility/Sonarr/SonarrCapabilityEnforcerTest.cs @@ -11,12 +11,12 @@ public class SonarrCapabilityEnforcerTest { [Test, AutoMockData] public void Fail_when_capabilities_not_obtained( - [Frozen] ISonarrCapabilityChecker checker, + [Frozen] ISonarrCapabilityFetcher fetcher, SonarrCapabilityEnforcer sut) { var config = NewConfig.Sonarr(); - checker.GetCapabilities(default!).ReturnsForAnyArgs((SonarrCapabilities?) null); + fetcher.GetCapabilities(default!).ReturnsForAnyArgs((SonarrCapabilities?) null); var act = () => sut.Check(config); @@ -25,12 +25,12 @@ public class SonarrCapabilityEnforcerTest [Test, AutoMockData] public void Minimum_version_not_met( - [Frozen] ISonarrCapabilityChecker checker, + [Frozen] ISonarrCapabilityFetcher fetcher, SonarrCapabilityEnforcer sut) { var config = NewConfig.Sonarr(); - checker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities(new Version()) + fetcher.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities { SupportsNamedReleaseProfiles = false }); @@ -42,7 +42,7 @@ public class SonarrCapabilityEnforcerTest [Test, AutoMockData] public void Release_profiles_not_allowed_in_v4( - [Frozen] ISonarrCapabilityChecker checker, + [Frozen] ISonarrCapabilityFetcher fetcher, SonarrCapabilityEnforcer sut) { var config = NewConfig.Sonarr() with @@ -53,7 +53,7 @@ public class SonarrCapabilityEnforcerTest } }; - checker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities(new Version()) + fetcher.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities { SupportsNamedReleaseProfiles = true, SupportsCustomFormats = true @@ -66,7 +66,7 @@ public class SonarrCapabilityEnforcerTest [Test, AutoMockData] public void Custom_formats_not_allowed_in_v3( - [Frozen] ISonarrCapabilityChecker checker, + [Frozen] ISonarrCapabilityFetcher fetcher, SonarrCapabilityEnforcer sut) { var config = NewConfig.Sonarr() with @@ -77,7 +77,7 @@ public class SonarrCapabilityEnforcerTest } }; - checker.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities(new Version()) + fetcher.GetCapabilities(default!).ReturnsForAnyArgs(new SonarrCapabilities { SupportsNamedReleaseProfiles = true, SupportsCustomFormats = false