refactor: Address internal sealed class warnings

- Made lots of classes internal & sealed as needed
- Removed Cli.TestLibrary project. TestLibrary projects are only useful
  if they're going to be reusable in other tests. The Cli project is at
  the bottom of the dependency chain and doesn't need to be reusable.
pull/433/head
Robert Dailey 2 months ago
parent e9a667e6ee
commit 173be37918

@ -42,6 +42,3 @@ dotnet_diagnostic.CA2007.severity = none
# Implement standard exception constructors
dotnet_diagnostic.CA1032.severity = none
# Consider making public types internal
dotnet_diagnostic.CA1515.severity = none

@ -32,6 +32,8 @@
<!-- For only NON-TEST projects -->
<ItemGroup Condition="!$(MSBuildProjectName.EndsWith('Tests'))">
<InternalsVisibleTo Include="$(MSBuildProjectName).Tests" />
<!-- For NSubstitute -->
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<!-- ReferenceTrimmer - run build with /p:EnableReferenceTrimmer=true to enable -->

@ -30,8 +30,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclarr.Core.TestLibrary"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclarr.Cli.Tests", "tests\Recyclarr.Cli.Tests\Recyclarr.Cli.Tests.csproj", "{59886A2A-338F-4864-9735-1633433B1F8F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclarr.Cli.TestLibrary", "tests\Recyclarr.Cli.TestLibrary\Recyclarr.Cli.TestLibrary.csproj", "{7B730BDB-1519-4847-BA23-998AB3750E31}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclarr.Core", "src\Recyclarr.Core\Recyclarr.Core.csproj", "{14F923B3-13EB-46D2-8AD0-D0811B46952A}"
EndProject
Global
@ -60,10 +58,6 @@ Global
{59886A2A-338F-4864-9735-1633433B1F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59886A2A-338F-4864-9735-1633433B1F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59886A2A-338F-4864-9735-1633433B1F8F}.Release|Any CPU.Build.0 = Release|Any CPU
{7B730BDB-1519-4847-BA23-998AB3750E31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B730BDB-1519-4847-BA23-998AB3750E31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B730BDB-1519-4847-BA23-998AB3750E31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B730BDB-1519-4847-BA23-998AB3750E31}.Release|Any CPU.Build.0 = Release|Any CPU
{14F923B3-13EB-46D2-8AD0-D0811B46952A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14F923B3-13EB-46D2-8AD0-D0811B46952A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14F923B3-13EB-46D2-8AD0-D0811B46952A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -80,6 +74,5 @@ Global
{A4EC7E0D-C591-4874-B9AC-EB12A96F3E83} = {18E17C53-F600-40AE-82C1-3CD1E547C307}
{DE198BA1-2906-43BB-9CDB-977B9218A670} = {18E17C53-F600-40AE-82C1-3CD1E547C307}
{59886A2A-338F-4864-9735-1633433B1F8F} = {18E17C53-F600-40AE-82C1-3CD1E547C307}
{7B730BDB-1519-4847-BA23-998AB3750E31} = {18E17C53-F600-40AE-82C1-3CD1E547C307}
EndGlobalSection
EndGlobal

@ -22,7 +22,7 @@ using Spectre.Console.Cli;
namespace Recyclarr.Cli;
public static class CompositionRoot
internal static class CompositionRoot
{
public static void Setup(ContainerBuilder builder)
{
@ -52,7 +52,7 @@ public static class CompositionRoot
builder.RegisterType<FlurlHttpExceptionHandler>();
// Sync
builder.RegisterType<SyncProcessor>().As<ISyncProcessor>();
builder.RegisterType<SyncProcessor>();
// Configuration
builder.RegisterType<ConfigCreationProcessor>().As<IConfigCreationProcessor>();
@ -70,7 +70,7 @@ public static class CompositionRoot
private static void RegisterMigrations(ContainerBuilder builder)
{
builder.RegisterType<MigrationExecutor>().As<IMigrationExecutor>();
builder.RegisterType<MigrationExecutor>();
// Migration Steps
builder

@ -5,7 +5,7 @@ using Spectre.Console.Cli;
namespace Recyclarr.Cli.Console;
public static class CliSetup
internal static class CliSetup
{
private static void AddCommands(IConfigurator cli)
{

@ -1,3 +1,3 @@
namespace Recyclarr.Cli.Console;
public class CommandException(string? message) : Exception(message);
internal class CommandException(string? message) : Exception(message);

@ -3,7 +3,7 @@ using Spectre.Console.Cli;
namespace Recyclarr.Cli.Console.Commands;
public class BaseCommandSettings : CommandSettings
internal class BaseCommandSettings : CommandSettings
{
public CancellationToken CancellationToken { get; set; }

@ -10,20 +10,19 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("Create a starter configuration file.")]
public class ConfigCreateCommand(
internal class ConfigCreateCommand(
ILogger log,
IConfigCreationProcessor processor,
IMultiRepoUpdater repoUpdater
) : AsyncCommand<ConfigCreateCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
[SuppressMessage(
"Performance",
"CA1819:Properties should not return arrays",
Justification = "Spectre.Console requires it"
)]
public class CliSettings : BaseCommandSettings, ICreateConfigSettings
internal class CliSettings : BaseCommandSettings, ICreateConfigSettings
{
[CommandOption("-p|--path")]
[Description("Path to where the configuration file should be created.")]

@ -9,13 +9,13 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List local configuration files.")]
public class ConfigListLocalCommand(
internal class ConfigListLocalCommand(
ConfigListLocalProcessor processor,
IMultiRepoUpdater repoUpdater
) : AsyncCommand<ConfigListLocalCommand.CliSettings>
{
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings;
internal class CliSettings : BaseCommandSettings;
public override async Task<int> ExecuteAsync(CommandContext context, CliSettings settings)
{

@ -1,5 +1,6 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Processors;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Repo;
@ -9,13 +10,13 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List local configuration files.")]
public class ConfigListTemplatesCommand(
internal class ConfigListTemplatesCommand(
ConfigListTemplateProcessor processor,
IMultiRepoUpdater repoUpdater
) : AsyncCommand<ConfigListTemplatesCommand.CliSettings>
{
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings, IConfigListTemplatesSettings
internal class CliSettings : BaseCommandSettings, IConfigListTemplatesSettings
{
[CommandOption("-i|--includes")]
[Description(
@ -32,8 +33,3 @@ public class ConfigListTemplatesCommand(
return (int)ExitStatus.Succeeded;
}
}
public interface IConfigListTemplatesSettings
{
bool Includes { get; }
}

@ -9,17 +9,16 @@ namespace Recyclarr.Cli.Console.Commands;
[Description("Delete things from services like Radarr and Sonarr")]
[UsedImplicitly]
public class DeleteCustomFormatsCommand(IDeleteCustomFormatsProcessor processor)
internal class DeleteCustomFormatsCommand(IDeleteCustomFormatsProcessor processor)
: AsyncCommand<DeleteCustomFormatsCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
[SuppressMessage(
"Performance",
"CA1819:Properties should not return arrays",
Justification = "Spectre.Console requires it"
)]
public class CliSettings : BaseCommandSettings, IDeleteCustomFormatSettings
internal class CliSettings : BaseCommandSettings, IDeleteCustomFormatSettings
{
[CommandArgument(0, "<instance_name>")]
[Description("The name of the instance to delete CFs from.")]

@ -14,12 +14,14 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List custom formats in the guide for a particular service.")]
public class ListCustomFormatsCommand(CustomFormatDataLister lister, IMultiRepoUpdater repoUpdater)
: AsyncCommand<ListCustomFormatsCommand.CliSettings>
internal class ListCustomFormatsCommand(
CustomFormatDataLister lister,
IMultiRepoUpdater repoUpdater
) : AsyncCommand<ListCustomFormatsCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings, IListCustomFormatSettings
internal class CliSettings : BaseCommandSettings, IListCustomFormatSettings
{
[CommandArgument(0, "<service_type>")]
[EnumDescription<SupportedServices>("The service type to obtain information about.")]

@ -11,12 +11,12 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List media naming formats in the guide for a particular service.")]
public class ListMediaNamingCommand(MediaNamingDataLister lister, IMultiRepoUpdater repoUpdater)
internal class ListMediaNamingCommand(MediaNamingDataLister lister, IMultiRepoUpdater repoUpdater)
: AsyncCommand<ListMediaNamingCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings
internal class CliSettings : BaseCommandSettings
{
[CommandArgument(0, "<service_type>")]
[EnumDescription<SupportedServices>("The service type to obtain information about.")]

@ -12,12 +12,12 @@ namespace Recyclarr.Cli.Console.Commands;
#pragma warning disable CS8765
[UsedImplicitly]
[Description("List quality definitions in the guide for a particular service.")]
public class ListQualitiesCommand(QualitySizeDataLister lister, IMultiRepoUpdater repoUpdater)
internal class ListQualitiesCommand(QualitySizeDataLister lister, IMultiRepoUpdater repoUpdater)
: AsyncCommand<ListQualitiesCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings
internal class CliSettings : BaseCommandSettings
{
[CommandArgument(0, "<service_type>")]
[EnumDescription<SupportedServices>("The service type to obtain information about.")]

@ -13,12 +13,12 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("Perform migration steps that may be needed between versions")]
public class MigrateCommand(IAnsiConsole console, IMigrationExecutor migration)
internal class MigrateCommand(IAnsiConsole console, MigrationExecutor migration)
: Command<MigrateCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings;
internal class CliSettings : BaseCommandSettings;
public override int Execute(CommandContext context, CliSettings settings)
{

@ -12,20 +12,19 @@ namespace Recyclarr.Cli.Console.Commands;
[Description("Sync the guide to services")]
[UsedImplicitly]
public class SyncCommand(
IMigrationExecutor migration,
internal class SyncCommand(
MigrationExecutor migration,
IMultiRepoUpdater repoUpdater,
ISyncProcessor syncProcessor
SyncProcessor syncProcessor
) : AsyncCommand<SyncCommand.CliSettings>
{
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
[SuppressMessage(
"Performance",
"CA1819:Properties should not return arrays",
Justification = "Spectre.Console requires it"
)]
public class CliSettings : BaseCommandSettings, ISyncSettings
internal class CliSettings : BaseCommandSettings, ISyncSettings
{
[CommandArgument(0, "[service]")]
[EnumDescription<SupportedServices>(

@ -6,7 +6,7 @@ using System.Text;
namespace Recyclarr.Cli.Console.Helpers;
[AttributeUsage(AttributeTargets.Property)]
public sealed class EnumDescriptionAttribute<TEnum> : DescriptionAttribute
internal sealed class EnumDescriptionAttribute<TEnum> : DescriptionAttribute
where TEnum : Enum
{
public override string Description { get; }

@ -0,0 +1,6 @@
namespace Recyclarr.Cli.Console.Settings;
internal interface IConfigListTemplatesSettings
{
bool Includes { get; }
}

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Console.Settings;
public interface ICreateConfigSettings
internal interface ICreateConfigSettings
{
public string? Path { get; }
public IReadOnlyCollection<string> Templates { get; }

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Console.Settings;
public interface IDeleteCustomFormatSettings
internal interface IDeleteCustomFormatSettings
{
public string InstanceName { get; }
public IReadOnlyCollection<string> CustomFormatNames { get; }

@ -2,7 +2,7 @@ using Recyclarr.TrashGuide;
namespace Recyclarr.Cli.Console.Settings;
public interface IListCustomFormatSettings
internal interface IListCustomFormatSettings
{
SupportedServices Service { get; }
bool ScoreSets { get; }

@ -2,7 +2,7 @@ using Recyclarr.TrashGuide;
namespace Recyclarr.Cli.Console.Settings;
public interface ISyncSettings
internal interface ISyncSettings
{
SupportedServices? Service { get; }
IReadOnlyCollection<string> Configs { get; }

@ -3,7 +3,7 @@ using Recyclarr.Platform;
namespace Recyclarr.Cli.Console.Setup;
public class AppDataDirSetupTask(IAppDataSetup appDataSetup) : IGlobalSetupTask
internal class AppDataDirSetupTask(IAppDataSetup appDataSetup) : IGlobalSetupTask
{
public void OnStart(BaseCommandSettings cmd)
{

@ -3,7 +3,7 @@ using Recyclarr.Cli.Console.Commands;
namespace Recyclarr.Cli.Console.Setup;
[UsedImplicitly]
public class CompositeGlobalSetupTask(IOrderedEnumerable<Lazy<IGlobalSetupTask>> tasks)
internal class CompositeGlobalSetupTask(IOrderedEnumerable<Lazy<IGlobalSetupTask>> tasks)
: IGlobalSetupTask
{
public void OnStart(BaseCommandSettings cmd)

@ -2,7 +2,7 @@ using Recyclarr.Cli.Console.Commands;
namespace Recyclarr.Cli.Console.Setup;
public interface IGlobalSetupTask
internal interface IGlobalSetupTask
{
void OnStart(BaseCommandSettings cmd);
void OnFinish();

@ -4,7 +4,7 @@ using Recyclarr.Settings;
namespace Recyclarr.Cli.Console.Setup;
public class JanitorCleanupTask(
internal class JanitorCleanupTask(
LogJanitor janitor,
ILogger log,
ISettings<LogJanitorSettings> settings

@ -6,7 +6,7 @@ using Serilog.Events;
namespace Recyclarr.Cli.Console.Setup;
public class LoggerSetupTask(
internal class LoggerSetupTask(
LoggingLevelSwitch loggingLevelSwitch,
LoggerFactory loggerFactory,
IEnumerable<ILogConfigurator> logConfigurators

@ -3,7 +3,7 @@ using Recyclarr.Platform;
namespace Recyclarr.Cli.Console.Setup;
public class ProgramInformationDisplayTask(ILogger log, IAppPaths paths) : IGlobalSetupTask
internal class ProgramInformationDisplayTask(ILogger log, IAppPaths paths) : IGlobalSetupTask
{
public void OnStart(BaseCommandSettings cmd)
{

@ -2,7 +2,7 @@ using Recyclarr.Platform;
namespace Recyclarr.Cli.Logging;
public class LogJanitor(IAppPaths paths)
internal class LogJanitor(IAppPaths paths)
{
public void DeleteOldestLogFiles(int numberOfNewestToKeep)
{

@ -6,7 +6,7 @@ using Serilog.Templates.Themes;
namespace Recyclarr.Cli.Logging;
public class LoggerFactory(IEnvironment env, LoggingLevelSwitch levelSwitch)
internal class LoggerFactory(IEnvironment env, LoggingLevelSwitch levelSwitch)
{
public ILogger Logger { get; private set; } =
LogSetup

@ -1,7 +0,0 @@
namespace Recyclarr.Cli.Migration;
public interface IMigrationExecutor
{
void PerformAllMigrationSteps(bool withDiagnostics);
void CheckNeededMigrations();
}

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Migration;
public class MigrationException(
internal class MigrationException(
Exception originalException,
string operationDescription,
IReadOnlyCollection<string> remediation

@ -3,10 +3,10 @@ using Spectre.Console;
namespace Recyclarr.Cli.Migration;
public class MigrationExecutor(
internal class MigrationExecutor(
IOrderedEnumerable<IMigrationStep> migrationSteps,
IAnsiConsole console
) : IMigrationExecutor
)
{
public void PerformAllMigrationSteps(bool withDiagnostics)
{

@ -1,3 +1,3 @@
namespace Recyclarr.Cli.Migration;
public class RequiredMigrationException() : Exception("Some REQUIRED migrations did not pass");
internal class RequiredMigrationException() : Exception("Some REQUIRED migrations did not pass");

@ -6,7 +6,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Migration.Steps;
[UsedImplicitly]
public class DeleteRepoDirMigrationStep(IAppPaths paths) : IMigrationStep
internal class DeleteRepoDirMigrationStep(IAppPaths paths) : IMigrationStep
{
public string Description => "Delete old repo directory";
public IReadOnlyCollection<string> Remediation =>

@ -2,7 +2,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Migration.Steps;
public interface IMigrationStep
internal interface IMigrationStep
{
/// <summary>
/// A description printed to the user so that they understand the purpose of this migration step, and

@ -5,7 +5,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Migration.Steps;
[UsedImplicitly]
public class MoveOsxAppDataDotnet8(
internal class MoveOsxAppDataDotnet8(
IAppPaths paths,
IEnvironment env,
IRuntimeInformation runtimeInfo,

@ -5,7 +5,7 @@ using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Cache;
public record TrashIdMapping(string TrashId, string CustomFormatName, int CustomFormatId);
internal record TrashIdMapping(string TrashId, string CustomFormatName, int CustomFormatId);
[CacheObjectName("custom-format-cache")]
[SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "POCO")]
@ -14,12 +14,12 @@ public record TrashIdMapping(string TrashId, string CustomFormatName, int Custom
"CA2227:Collection properties should be read only",
Justification = "POCO"
)]
public record CustomFormatCacheObject() : CacheObject(1)
internal record CustomFormatCacheObject() : CacheObject(1)
{
public List<TrashIdMapping> TrashIdMappings { get; set; } = [];
}
public class CustomFormatCache(CustomFormatCacheObject cacheObject) : BaseCache(cacheObject)
internal class CustomFormatCache(CustomFormatCacheObject cacheObject) : BaseCache(cacheObject)
{
public IReadOnlyList<TrashIdMapping> TrashIdMappings => cacheObject.TrashIdMappings;

@ -3,7 +3,7 @@ using Recyclarr.Config.Models;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Cache;
public class CustomFormatCachePersister(
internal class CustomFormatCachePersister(
ILogger log,
ICacheStoragePath storagePath,
IServiceConfiguration config

@ -5,7 +5,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Pipelines.CustomFormat;
public class CustomFormatDataLister(IAnsiConsole console, ICustomFormatGuideService guide)
internal class CustomFormatDataLister(IAnsiConsole console, ICustomFormatGuideService guide)
{
public void List(IListCustomFormatSettings settings)
{

@ -2,4 +2,4 @@ using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Models;
public record ConflictingCustomFormat(CustomFormatData GuideCf, int ConflictingId);
internal record ConflictingCustomFormat(CustomFormatData GuideCf, int ConflictingId);

@ -4,7 +4,7 @@ using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Models;
public record CustomFormatTransactionData
internal record CustomFormatTransactionData
{
public Collection<TrashIdMapping> DeletedCustomFormats { get; } = [];
public Collection<CustomFormatData> NewCustomFormats { get; } = [];

@ -1,10 +0,0 @@
using Recyclarr.Config.Models;
using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Models;
public class ProcessedConfigData
{
public ICollection<CustomFormatData> CustomFormats { get; init; } = [];
public ICollection<AssignScoresToConfig> QualityProfiles { get; init; } = [];
}

@ -3,7 +3,7 @@ using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.CustomFormat.Models;
public class ProcessedCustomFormatCache : IPipelineCache
internal class ProcessedCustomFormatCache : IPipelineCache
{
private readonly List<CustomFormatData> _customFormats = [];

@ -3,7 +3,7 @@ namespace Recyclarr.Cli.Pipelines;
/// <summary>
/// Defines a mechanism for state sharing between pipelines.
/// </summary>
public interface IPipelineCache
internal interface IPipelineCache
{
void Clear();
}

@ -2,9 +2,9 @@ using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Pipelines;
// This interface is valuable because it allows having a collection of generic sync pipelines without needing to be
// aware of the generic parameters.
public interface ISyncPipeline
// This interface is valuable because it allows having a collection of generic sync pipelines
// without needing to be aware of the generic parameters.
internal interface ISyncPipeline
{
public Task Execute(ISyncSettings settings, CancellationToken ct);
}

@ -6,7 +6,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Pipelines.MediaNaming;
public class MediaNamingDataLister(IAnsiConsole console, IMediaNamingGuideService guide)
internal class MediaNamingDataLister(IAnsiConsole console, IMediaNamingGuideService guide)
{
public void ListNaming(SupportedServices serviceType)
{

@ -3,7 +3,7 @@ using Recyclarr.TrashGuide.MediaNaming;
namespace Recyclarr.Cli.Pipelines.MediaNaming.PipelinePhases.Config;
public interface IServiceBasedMediaNamingConfigPhase
internal interface IServiceBasedMediaNamingConfigPhase
{
Task<MediaNamingDto> ProcessNaming(IMediaNamingGuideService guide, NamingFormatLookup lookup);
}

@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis;
namespace Recyclarr.Cli.Pipelines.MediaNaming.PipelinePhases.Config;
public class NamingFormatLookup
internal class NamingFormatLookup
{
private readonly List<InvalidNamingConfig> _errors = [];
public IReadOnlyCollection<InvalidNamingConfig> Errors => _errors;

@ -4,7 +4,7 @@ using Recyclarr.TrashGuide.MediaNaming;
namespace Recyclarr.Cli.Pipelines.MediaNaming.PipelinePhases.Config;
public class RadarrMediaNamingConfigPhase(RadarrConfiguration config)
internal class RadarrMediaNamingConfigPhase(RadarrConfiguration config)
: IServiceBasedMediaNamingConfigPhase
{
public Task<MediaNamingDto> ProcessNaming(

@ -4,7 +4,7 @@ using Recyclarr.TrashGuide.MediaNaming;
namespace Recyclarr.Cli.Pipelines.MediaNaming.PipelinePhases.Config;
public class SonarrMediaNamingConfigPhase(SonarrConfiguration config)
internal class SonarrMediaNamingConfigPhase(SonarrConfiguration config)
: IServiceBasedMediaNamingConfigPhase
{
public Task<MediaNamingDto> ProcessNaming(

@ -7,9 +7,9 @@ using Recyclarr.TrashGuide.MediaNaming;
namespace Recyclarr.Cli.Pipelines.MediaNaming.PipelinePhases;
public record InvalidNamingConfig(string Type, string ConfigValue);
internal record InvalidNamingConfig(string Type, string ConfigValue);
public record ProcessedNamingConfig
internal record ProcessedNamingConfig
{
public required MediaNamingDto Dto { get; init; }
public IReadOnlyCollection<InvalidNamingConfig> InvalidNaming { get; init; } = [];

@ -19,7 +19,7 @@ using Recyclarr.TrashGuide.QualitySize;
namespace Recyclarr.Cli.Pipelines;
public class PipelineAutofacModule : Module
internal class PipelineAutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{

@ -3,9 +3,14 @@ using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Pipelines.QualityProfile.Models;
public record ProcessedQualityProfileScore(string TrashId, string CfName, int FormatId, int Score);
internal record ProcessedQualityProfileScore(
string TrashId,
string CfName,
int FormatId,
int Score
);
public record ProcessedQualityProfileData
internal record ProcessedQualityProfileData
{
public required QualityProfileConfig Profile { get; init; }
public bool ShouldCreate { get; init; } = true;

@ -2,7 +2,7 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile.Models;
public record QualityProfileServiceData(
internal record QualityProfileServiceData(
IReadOnlyList<QualityProfileDto> Profiles,
QualityProfileDto Schema
);

@ -3,13 +3,13 @@ using FluentValidation.Results;
namespace Recyclarr.Cli.Pipelines.QualityProfile.Models;
public record InvalidProfileData(
internal record InvalidProfileData(
UpdatedQualityProfile Profile,
IReadOnlyCollection<ValidationFailure> Errors
);
[SuppressMessage("Usage", "CA2227:Collection properties should be read only")]
public record QualityProfileTransactionData
internal record QualityProfileTransactionData
{
public ICollection<string> NonExistentProfiles { get; init; } = [];
public ICollection<InvalidProfileData> InvalidProfiles { get; init; } = [];

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Pipelines.QualityProfile.Models;
public enum QualityProfileUpdateReason
internal enum QualityProfileUpdateReason
{
New,
Changed,

@ -5,7 +5,7 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public class QualityItemOrganizer
internal class QualityItemOrganizer
{
private readonly List<string> _invalidItemNames = [];

@ -3,7 +3,7 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public static class QualityProfileExtensions
internal static class QualityProfileExtensions
{
private static IEnumerable<ProfileItemDto> FlattenItems(IEnumerable<ProfileItemDto> items)
{

@ -4,7 +4,7 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public record ProfileWithStats
internal record ProfileWithStats
{
public required UpdatedQualityProfile Profile { get; set; }
public bool ProfileChanged { get; set; }
@ -14,7 +14,7 @@ public record ProfileWithStats
public bool HasChanges => ProfileChanged || ScoresChanged || QualitiesChanged;
}
public class QualityProfileStatCalculator(ILogger log)
internal class QualityProfileStatCalculator(ILogger log)
{
public ProfileWithStats Calculate(UpdatedQualityProfile profile)
{

@ -4,7 +4,7 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public enum FormatScoreUpdateReason
internal enum FormatScoreUpdateReason
{
/// <summary>
/// A score who's value did not change.
@ -29,7 +29,7 @@ public enum FormatScoreUpdateReason
New,
}
public record UpdatedFormatScore(
internal record UpdatedFormatScore(
ProfileFormatItemDto Dto,
int NewScore,
FormatScoreUpdateReason Reason

@ -3,14 +3,14 @@ using Recyclarr.ServarrApi.QualityProfile;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public record UpdatedQualities
internal record UpdatedQualities
{
public ICollection<string> InvalidQualityNames { get; init; } = [];
public IReadOnlyCollection<ProfileItemDto> Items { get; init; } = [];
public int NumWantedItems { get; init; }
}
public record UpdatedQualityProfile
internal record UpdatedQualityProfile
{
public required QualityProfileDto ProfileDto { get; init; }
public required ProcessedQualityProfileData ProfileConfig { get; init; }

@ -4,7 +4,7 @@ using Recyclarr.Common.Extensions;
namespace Recyclarr.Cli.Pipelines.QualityProfile;
public class UpdatedQualityProfileValidator : AbstractValidator<UpdatedQualityProfile>
internal class UpdatedQualityProfileValidator : AbstractValidator<UpdatedQualityProfile>
{
public UpdatedQualityProfileValidator()
{

@ -3,7 +3,7 @@ using Recyclarr.TrashGuide.QualitySize;
namespace Recyclarr.Cli.Pipelines.QualitySize.PipelinePhases.Limits;
public interface IQualityItemLimitFactory
internal interface IQualityItemLimitFactory
{
Task<QualityItemLimits> Create(SupportedServices serviceType, CancellationToken ct);
}

@ -4,7 +4,7 @@ using Recyclarr.TrashGuide.QualitySize;
namespace Recyclarr.Cli.Pipelines.QualitySize.PipelinePhases.Limits;
public class QualityItemLimitFactory(
internal class QualityItemLimitFactory(
IIndex<SupportedServices, IQualityItemLimitFetcher> limitFactory
) : IQualityItemLimitFactory
{

@ -3,7 +3,7 @@ using Recyclarr.TrashGuide.QualitySize;
namespace Recyclarr.Cli.Pipelines.QualitySize.PipelinePhases.Limits;
public class RadarrQualityItemLimitFetcher(IRadarrCapabilityFetcher capabilityFetcher)
internal class RadarrQualityItemLimitFetcher(IRadarrCapabilityFetcher capabilityFetcher)
: IQualityItemLimitFetcher
{
private QualityItemLimits? _cachedLimits;

@ -3,7 +3,7 @@ using Recyclarr.TrashGuide.QualitySize;
namespace Recyclarr.Cli.Pipelines.QualitySize.PipelinePhases.Limits;
public class SonarrQualityItemLimitFetcher(ISonarrCapabilityFetcher capabilityFetcher)
internal class SonarrQualityItemLimitFetcher(ISonarrCapabilityFetcher capabilityFetcher)
: IQualityItemLimitFetcher
{
private QualityItemLimits? _cachedLimits;

@ -4,7 +4,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Pipelines.QualitySize;
public class QualitySizeDataLister(IAnsiConsole console, IQualitySizeGuideService guide)
internal class QualitySizeDataLister(IAnsiConsole console, IQualitySizeGuideService guide)
{
public void ListQualities(SupportedServices serviceType)
{

@ -2,7 +2,7 @@ using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Processors.Config;
public class ConfigCreationProcessor(IOrderedEnumerable<IConfigCreator> creators)
internal class ConfigCreationProcessor(IOrderedEnumerable<IConfigCreator> creators)
: IConfigCreationProcessor
{
public void Process(ICreateConfigSettings settings)

@ -9,7 +9,7 @@ using Spectre.Console.Rendering;
namespace Recyclarr.Cli.Processors.Config;
public class ConfigListLocalProcessor(
internal class ConfigListLocalProcessor(
IAnsiConsole console,
ConfigurationRegistry configRegistry,
IAppPaths paths

@ -1,11 +1,11 @@
using System.Globalization;
using Recyclarr.Cli.Console.Commands;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.TrashGuide;
using Spectre.Console;
namespace Recyclarr.Cli.Processors.Config;
public class ConfigListTemplateProcessor(
internal class ConfigListTemplateProcessor(
IAnsiConsole console,
IConfigTemplateGuideService guideService
)

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Processors.Config;
public class FileExistsException(string attemptedPath)
internal class FileExistsException(string attemptedPath)
: Exception($"File already exists: {attemptedPath}")
{
public string AttemptedPath { get; } = attemptedPath;

@ -2,7 +2,7 @@ using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Processors.Config;
public interface IConfigCreationProcessor
internal interface IConfigCreationProcessor
{
void Process(ICreateConfigSettings settings);
}

@ -2,7 +2,7 @@ using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Processors.Config;
public interface IConfigCreator
internal interface IConfigCreator
{
bool CanHandle(ICreateConfigSettings settings);
void Create(ICreateConfigSettings settings);

@ -6,7 +6,7 @@ using Recyclarr.Platform;
namespace Recyclarr.Cli.Processors.Config;
public class LocalConfigCreator(
internal class LocalConfigCreator(
ILogger log,
IAppPaths paths,
IFileSystem fs,

@ -6,7 +6,7 @@ using Recyclarr.TrashGuide;
namespace Recyclarr.Cli.Processors.Config;
public class TemplateConfigCreator(
internal class TemplateConfigCreator(
ILogger log,
IConfigTemplateGuideService templates,
IAppPaths paths

@ -19,7 +19,7 @@ internal class CustomFormatConfigurationScope(ILifetimeScope scope) : Configurat
scope.Resolve<ICustomFormatApiService>();
}
public class DeleteCustomFormatsProcessor(
internal class DeleteCustomFormatsProcessor(
ILogger log,
IAnsiConsole console,
ConfigurationRegistry configRegistry,

@ -2,7 +2,7 @@ using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Processors.Delete;
public interface IDeleteCustomFormatsProcessor
internal interface IDeleteCustomFormatsProcessor
{
Task Process(IDeleteCustomFormatSettings settings, CancellationToken ct);
}

@ -10,7 +10,7 @@ using YamlDotNet.Core;
namespace Recyclarr.Cli.Processors.ErrorHandling;
public class ConsoleExceptionHandler(ILogger log)
internal class ConsoleExceptionHandler(ILogger log)
{
public async Task<bool> HandleException(Exception sourceException)
{

@ -5,7 +5,7 @@ using Recyclarr.Json;
namespace Recyclarr.Cli.Processors.ErrorHandling;
public sealed class ErrorResponseParser(ILogger log, string responseBody)
internal sealed class ErrorResponseParser(ILogger log, string responseBody)
{
private readonly Func<Stream> _streamFactory = () =>
new MemoryStream(Encoding.UTF8.GetBytes(responseBody));

@ -3,7 +3,7 @@ using Recyclarr.Common.Extensions;
namespace Recyclarr.Cli.Processors.ErrorHandling;
public class FlurlHttpExceptionHandler(ILogger log)
internal class FlurlHttpExceptionHandler(ILogger log)
{
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
public async Task ProcessServiceErrorMessages(IServiceErrorMessageExtractor extractor)

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Processors.ErrorHandling;
public interface IServiceErrorMessageExtractor
internal interface IServiceErrorMessageExtractor
{
Task<string> GetErrorMessage();
int? HttpStatusCode { get; }

@ -2,7 +2,7 @@ using Flurl.Http;
namespace Recyclarr.Cli.Processors.ErrorHandling;
public class ServiceErrorMessageExtractor(FlurlHttpException e) : IServiceErrorMessageExtractor
internal class ServiceErrorMessageExtractor(FlurlHttpException e) : IServiceErrorMessageExtractor
{
public HttpRequestError? HttpError
{

@ -1,6 +1,6 @@
namespace Recyclarr.Cli.Processors;
public enum ExitStatus
internal enum ExitStatus
{
Succeeded = 0,
Failed,

@ -1,4 +1,4 @@
namespace Recyclarr.Cli.Processors;
public class FatalException(string? message, Exception? innerException = null)
internal class FatalException(string? message, Exception? innerException = null)
: Exception(message, innerException);

@ -1,9 +0,0 @@
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Config.Models;
namespace Recyclarr.Cli.Processors;
public interface IServiceProcessor
{
Task Process(ISyncSettings settings, IServiceConfiguration config);
}

@ -1,8 +0,0 @@
using Recyclarr.Cli.Console.Settings;
namespace Recyclarr.Cli.Processors.Sync;
public interface ISyncProcessor
{
Task<ExitStatus> Process(ISyncSettings settings, CancellationToken ct);
}

@ -12,19 +12,19 @@ using Spectre.Console;
namespace Recyclarr.Cli.Processors.Sync;
[UsedImplicitly]
public class SyncBasedConfigurationScope(ILifetimeScope scope) : ConfigurationScope(scope)
internal class SyncBasedConfigurationScope(ILifetimeScope scope) : ConfigurationScope(scope)
{
public ISyncPipeline Pipelines { get; } = scope.Resolve<ISyncPipeline>();
}
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
public class SyncProcessor(
internal class SyncProcessor(
IAnsiConsole console,
ConfigurationRegistry configRegistry,
ConfigurationScopeFactory configScopeFactory,
ConsoleExceptionHandler exceptionHandler,
NotificationService notify
) : ISyncProcessor
)
{
public async Task<ExitStatus> Process(ISyncSettings settings, CancellationToken ct)
{

@ -1,3 +1,2 @@
global using JetBrains.Annotations;
global using Serilog;
global using SuperLinq;

@ -6,7 +6,7 @@
<DefaultItemExcludes>$(DefaultItemExcludes);TestResults\*\**</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<ItemGroup Condition="$(MSBuildProjectName.EndsWith('.Tests'))">
<!-- Packages that apply to all tests -->
<PackageReference Include="AgileObjects.ReadableExpressions" />
<PackageReference Include="AutofacContrib.NSubstitute" />
@ -30,7 +30,7 @@
<PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition="$(MSBuildProjectName.EndsWith('.Tests'))">
<Using Include="AutoFixture.NUnit4" />
<Using Include="FluentAssertions" />
<Using Include="NSubstitute" />

@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\src\Recyclarr.Cli\Recyclarr.Cli.csproj" />
<ProjectReference Include="..\..\src\Recyclarr.Core\Recyclarr.Core.csproj" />
<ProjectReference Include="..\Recyclarr.Core.TestLibrary\Recyclarr.Core.TestLibrary.csproj" />
</ItemGroup>
</Project>

@ -1,12 +1,11 @@
using Recyclarr.Cli.Pipelines.CustomFormat.Cache;
using Recyclarr.Cli.Pipelines.CustomFormat.Models;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Core.TestLibrary;
namespace Recyclarr.Cli.Tests.Cache;
[TestFixture]
public class CustomFormatCacheTest
internal sealed class CustomFormatCacheTest
{
[Test]
public void New_updated_and_changed_are_added()

@ -1,9 +1,8 @@
using AutoMapper;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class AutoMapperConfigurationTest : CliIntegrationFixture
{
[Test]

@ -1,11 +1,10 @@
using System.IO.Abstractions;
using Recyclarr.Cli.Console.Setup;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Settings;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class BaseCommandSetupIntegrationTest : CliIntegrationFixture
{
[Test]

@ -1,6 +1,6 @@
using System.IO.Abstractions;
using Recyclarr.Cli.Console;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Repo;
using Recyclarr.TestLibrary;
using Spectre.Console.Cli;

@ -10,8 +10,7 @@ using Spectre.Console;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
public class CompositionRootTest
internal sealed class CompositionRootTest
{
[SuppressMessage(
"Microsoft.Performance",

@ -2,12 +2,11 @@ using System.IO.Abstractions;
using Recyclarr.Cli.Console.Commands;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Repo;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class ConfigCreationProcessorIntegrationTest : CliIntegrationFixture
{
[Test]

@ -2,14 +2,13 @@ using Recyclarr.Cli.Pipelines.CustomFormat;
using Recyclarr.Cli.Pipelines.CustomFormat.Cache;
using Recyclarr.Cli.Pipelines.CustomFormat.Models;
using Recyclarr.Cli.Pipelines.CustomFormat.PipelinePhases;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Config;
using Recyclarr.Core.TestLibrary;
using Recyclarr.TrashGuide.CustomFormat;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class CustomFormatTransactionPhaseTest : CliIntegrationFixture
{
[Test]

@ -1,10 +1,9 @@
using System.IO.Abstractions;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Settings;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class ServiceCompatibilityIntegrationTest : CliIntegrationFixture
{
[Test]

@ -1,12 +1,11 @@
using System.IO.Abstractions;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Cli.TestLibrary;
using Recyclarr.Cli.Tests.Reusable;
using Recyclarr.Repo;
namespace Recyclarr.Cli.Tests.IntegrationTests;
[TestFixture]
internal sealed class TemplateConfigCreatorIntegrationTest : CliIntegrationFixture
{
[Test]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save