You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
recyclarr/src/Recyclarr.Config/Parsing/PostProcessing/IncludePostProcessor.cs

99 lines
3.0 KiB

using Recyclarr.Config.Parsing.PostProcessing.ConfigMerging;
using Recyclarr.Platform;
using Recyclarr.TrashGuide;
using Serilog.Context;
namespace Recyclarr.Config.Parsing.PostProcessing;
public class IncludePostProcessor(
ILogger log,
ConfigParser parser,
ConfigValidationExecutor validator,
IYamlIncludeResolver includeResolver)
: IConfigPostProcessor
{
public RootConfigYaml Process(RootConfigYaml config)
{
return new RootConfigYaml
{
Radarr = ProcessIncludes(config.Radarr, new RadarrConfigMerger(), SupportedServices.Radarr),
Sonarr = ProcessIncludes(config.Sonarr, new SonarrConfigMerger(), SupportedServices.Sonarr)
};
}
private Dictionary<string, T>? ProcessIncludes<T>(
IReadOnlyDictionary<string, T>? configs,
ServiceConfigMerger<T> merger,
SupportedServices serviceType)
where T : ServiceConfigYaml, new()
{
if (configs is null)
{
return null;
}
var mergedConfigs = new Dictionary<string, T>();
foreach (var (key, config) in configs)
{
if (config.Include is null)
{
mergedConfigs.Add(key, config);
continue;
}
// Combine all includes together first
var aggregateInclude = config.Include
.Select(x => LoadYamlInclude<T>(x, serviceType))
.Aggregate(new T(), merger.Merge);
// Merge the config into the aggregated includes so that root config values overwrite included values.
mergedConfigs.Add(key, merger.Merge(aggregateInclude, config) with
{
BaseUrl = config.BaseUrl,
ApiKey = config.ApiKey,
// No reason to keep these around anymore now that they have been merged
Include = null
});
}
return mergedConfigs;
}
private T LoadYamlInclude<T>(IYamlInclude includeType, SupportedServices serviceType)
where T : ServiceConfigYaml
{
var yamlFile = includeResolver.GetIncludePath(includeType, serviceType);
using var logScope = LogContext.PushProperty(LogProperty.Scope, $"Include {yamlFile.Name}");
var configToMerge = parser.Load<T>(yamlFile);
if (configToMerge is null)
{
throw new YamlIncludeException($"Failed to parse include file: {yamlFile.FullName}");
}
if (!validator.Validate(configToMerge))
{
throw new YamlIncludeException($"Validation of included YAML failed: {yamlFile.FullName}");
}
if (configToMerge.BaseUrl is not null)
{
log.Warning("`base_url` is not allowed in YAML includes");
}
if (configToMerge.ApiKey is not null)
{
log.Warning("`api_key` is not allowed in YAML includes");
}
if (configToMerge.Include is not null)
{
log.Warning("Nested `include` directives are not supported");
}
return configToMerge;
}
}