From 2fe29f3b16ae36714cdc6c844ede6c0109fce5ce Mon Sep 17 00:00:00 2001 From: Robert Dailey Date: Thu, 23 Dec 2021 12:26:09 -0600 Subject: [PATCH] feat: settings functionality A settings file, `settings.yml` is now available which stores global configuration such as the clone URL for the Github Trash repository. --- CHANGELOG.md | 8 +++ src/Directory.Build.props | 5 +- src/Directory.Build.targets | 1 + .../AutoFixture/AutofacSpecimenBuilder.cs | 1 - .../InlineAutoMockDataAttribute.cs | 2 +- .../Services/ConfigurationLoaderTest.cs | 2 +- src/Trash/AppPaths.cs | 2 + src/Trash/Command/RadarrCommand.cs | 5 +- src/Trash/Command/ServiceCommand.cs | 12 +++- src/Trash/Command/SonarrCommand.cs | 5 +- src/Trash/Config/ConfigurationLoader.cs | 4 +- src/Trash/Config/IConfigurationLoader.cs | 1 - src/Trash/ResourcePaths.cs | 1 + src/TrashLib.Tests/Cache/ServiceCacheTest.cs | 1 - .../Config/Settings/SettingsPersisterTest.cs | 69 ++++++++++++++++++ .../Config/Settings/SettingsProviderTest.cs | 19 +++++ .../Processors/PersistenceProcessorTest.cs | 1 - src/TrashLib/Cache/ServiceCache.cs | 1 - src/TrashLib/Config/ConfigAutofacModule.cs | 10 +-- .../Config/Settings/ISettingsPersister.cs | 6 ++ .../Config/Settings/ISettingsProvider.cs | 7 ++ .../Config/Settings/SettingsPersister.cs | 51 ++++++++++++++ .../Config/Settings/SettingsProvider.cs | 11 +++ .../Config/Settings/SettingsValues.cs | 11 +++ src/TrashLib/Radarr/Config/IResourcePaths.cs | 1 + .../Radarr/Config/RadarrConfiguration.cs | 1 - .../CustomFormat/Api/CustomFormatService.cs | 1 - .../CustomFormat/Api/QualityProfileService.cs | 1 - .../Guide/LocalRepoCustomFormatJsonParser.cs | 70 +++++++++++++------ .../Processors/PersistenceProcessor.cs | 1 - .../Api/QualityDefinitionService.cs | 1 - src/TrashLib/Radarr/RadarrAutofacModule.cs | 1 - src/TrashLib/Sonarr/Api/SonarrApi.cs | 1 - .../Sonarr/Config/SonarrConfiguration.cs | 1 - src/TrashLib/Sonarr/SonarrCompatibility.cs | 1 - wiki/Home.md | 1 + wiki/Settings-Reference.md | 36 ++++++++++ 37 files changed, 300 insertions(+), 53 deletions(-) create mode 100644 src/TrashLib.Tests/Config/Settings/SettingsPersisterTest.cs create mode 100644 src/TrashLib.Tests/Config/Settings/SettingsProviderTest.cs create mode 100644 src/TrashLib/Config/Settings/ISettingsPersister.cs create mode 100644 src/TrashLib/Config/Settings/ISettingsProvider.cs create mode 100644 src/TrashLib/Config/Settings/SettingsPersister.cs create mode 100644 src/TrashLib/Config/Settings/SettingsProvider.cs create mode 100644 src/TrashLib/Config/Settings/SettingsValues.cs create mode 100644 wiki/Settings-Reference.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f3aab9..512b8841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- New settings file to control non-service specific behavior of Trash Updater. See [the + documentation](setref) for more information. +- Trash git repository URL can be overridden in settings. + +[setref]: https://github.com/rcdailey/trash-updater/wiki/Settings-Reference + ### Fixed - Remove `System.Reactive.xml` from the published ZIP files. diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 72139f8a..371fcda0 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -38,10 +38,11 @@ + - + @@ -53,7 +54,7 @@ - + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 51c5b49f..e435b82e 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -36,6 +36,7 @@ + diff --git a/src/TestLibrary/AutoFixture/AutofacSpecimenBuilder.cs b/src/TestLibrary/AutoFixture/AutofacSpecimenBuilder.cs index f9dd1fd1..f407b68b 100644 --- a/src/TestLibrary/AutoFixture/AutofacSpecimenBuilder.cs +++ b/src/TestLibrary/AutoFixture/AutofacSpecimenBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; using Autofac; using AutoFixture.Kernel; diff --git a/src/TestLibrary/AutoFixture/InlineAutoMockDataAttribute.cs b/src/TestLibrary/AutoFixture/InlineAutoMockDataAttribute.cs index 97683961..e7b40f45 100644 --- a/src/TestLibrary/AutoFixture/InlineAutoMockDataAttribute.cs +++ b/src/TestLibrary/AutoFixture/InlineAutoMockDataAttribute.cs @@ -3,7 +3,7 @@ using AutoFixture.NUnit3; namespace TestLibrary.AutoFixture; -public class InlineAutoMockDataAttribute : InlineAutoDataAttribute +public sealed class InlineAutoMockDataAttribute : InlineAutoDataAttribute { [SuppressMessage("Design", "CA1019", MessageId = "Define accessors for attribute arguments", Justification = "The parameter is forwarded to the base class and not used directly")] diff --git a/src/Trash.Tests/Config/Services/ConfigurationLoaderTest.cs b/src/Trash.Tests/Config/Services/ConfigurationLoaderTest.cs index 44b2b21e..c4d79ca6 100644 --- a/src/Trash.Tests/Config/Services/ConfigurationLoaderTest.cs +++ b/src/Trash.Tests/Config/Services/ConfigurationLoaderTest.cs @@ -42,7 +42,7 @@ public class ConfigurationLoaderTest { var builder = new ContainerBuilder(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); return builder.Build(); } diff --git a/src/Trash/AppPaths.cs b/src/Trash/AppPaths.cs index abd4be7d..b4fa4750 100644 --- a/src/Trash/AppPaths.cs +++ b/src/Trash/AppPaths.cs @@ -10,6 +10,8 @@ internal static class AppPaths public static string DefaultConfigPath { get; } = Path.Combine(AppContext.BaseDirectory, "trash.yml"); + public static string DefaultSettingsPath { get; } = Path.Combine(AppDataPath, "settings.yml"); + public static string LogDirectory { get; } = Path.Combine(AppDataPath, "logs"); public static string RepoDirectory { get; } = Path.Combine(AppDataPath, "repo"); diff --git a/src/Trash/Command/RadarrCommand.cs b/src/Trash/Command/RadarrCommand.cs index 347351c5..c3ef4862 100644 --- a/src/Trash/Command/RadarrCommand.cs +++ b/src/Trash/Command/RadarrCommand.cs @@ -6,8 +6,8 @@ using Flurl.Http; using JetBrains.Annotations; using Serilog; using Serilog.Core; -using Trash.Command.Helpers; using Trash.Config; +using TrashLib.Config.Settings; using TrashLib.Radarr.Config; using TrashLib.Radarr.CustomFormat; using TrashLib.Radarr.QualityDefinition; @@ -27,10 +27,11 @@ public class RadarrCommand : ServiceCommand ILogger log, LoggingLevelSwitch loggingLevelSwitch, ILogJanitor logJanitor, + ISettingsPersister settingsPersister, IConfigurationLoader configLoader, Func qualityUpdaterFactory, Func customFormatUpdaterFactory) - : base(log, loggingLevelSwitch, logJanitor) + : base(log, loggingLevelSwitch, logJanitor, settingsPersister) { _log = log; _configLoader = configLoader; diff --git a/src/Trash/Command/ServiceCommand.cs b/src/Trash/Command/ServiceCommand.cs index 247707a9..fea39d6d 100644 --- a/src/Trash/Command/ServiceCommand.cs +++ b/src/Trash/Command/ServiceCommand.cs @@ -12,6 +12,7 @@ using Newtonsoft.Json; using Serilog; using Serilog.Core; using Serilog.Events; +using TrashLib.Config.Settings; using TrashLib.Extensions; using YamlDotNet.Core; @@ -22,20 +23,24 @@ public abstract class ServiceCommand : ICommand, IServiceCommand private readonly ILogger _log; private readonly LoggingLevelSwitch _loggingLevelSwitch; private readonly ILogJanitor _logJanitor; + private readonly ISettingsPersister _settingsPersister; protected ServiceCommand( ILogger log, LoggingLevelSwitch loggingLevelSwitch, - ILogJanitor logJanitor) + ILogJanitor logJanitor, + ISettingsPersister settingsPersister) { _loggingLevelSwitch = loggingLevelSwitch; _logJanitor = logJanitor; + _settingsPersister = settingsPersister; _log = log; } public async ValueTask ExecuteAsync(IConsole console) { SetupLogging(); + LoadSettings(); SetupHttp(); try @@ -65,6 +70,11 @@ public abstract class ServiceCommand : ICommand, IServiceCommand } } + private void LoadSettings() + { + _settingsPersister.Load(); + } + [CommandOption("preview", 'p', Description = "Only display the processed markdown results without making any API calls.")] public bool Preview { get; [UsedImplicitly] set; } = false; diff --git a/src/Trash/Command/SonarrCommand.cs b/src/Trash/Command/SonarrCommand.cs index 8806364e..16efebaa 100644 --- a/src/Trash/Command/SonarrCommand.cs +++ b/src/Trash/Command/SonarrCommand.cs @@ -6,8 +6,8 @@ using Flurl.Http; using JetBrains.Annotations; using Serilog; using Serilog.Core; -using Trash.Command.Helpers; using Trash.Config; +using TrashLib.Config.Settings; using TrashLib.Sonarr.Config; using TrashLib.Sonarr.QualityDefinition; using TrashLib.Sonarr.ReleaseProfile; @@ -27,10 +27,11 @@ public class SonarrCommand : ServiceCommand ILogger log, LoggingLevelSwitch loggingLevelSwitch, ILogJanitor logJanitor, + ISettingsPersister settingsPersister, IConfigurationLoader configLoader, Func profileUpdaterFactory, Func qualityUpdaterFactory) - : base(log, loggingLevelSwitch, logJanitor) + : base(log, loggingLevelSwitch, logJanitor, settingsPersister) { _log = log; _configLoader = configLoader; diff --git a/src/Trash/Config/ConfigurationLoader.cs b/src/Trash/Config/ConfigurationLoader.cs index 270eba9e..86a712fe 100644 --- a/src/Trash/Config/ConfigurationLoader.cs +++ b/src/Trash/Config/ConfigurationLoader.cs @@ -22,13 +22,13 @@ public class ConfigurationLoader : IConfigurationLoader public ConfigurationLoader( IConfigurationProvider configProvider, IFileSystem fileSystem, - IYamlDeserializerFactory yamlFactory, + IYamlSerializerFactory yamlFactory, IValidator validator) { _configProvider = configProvider; _fileSystem = fileSystem; _validator = validator; - _deserializer = yamlFactory.Create(); + _deserializer = yamlFactory.CreateDeserializer(); } public IEnumerable Load(string propertyName, string configSection) diff --git a/src/Trash/Config/IConfigurationLoader.cs b/src/Trash/Config/IConfigurationLoader.cs index c0f7dfd2..1cd76ae4 100644 --- a/src/Trash/Config/IConfigurationLoader.cs +++ b/src/Trash/Config/IConfigurationLoader.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using TrashLib.Config; using TrashLib.Config.Services; namespace Trash.Config; diff --git a/src/Trash/ResourcePaths.cs b/src/Trash/ResourcePaths.cs index 9376dd85..349531d0 100644 --- a/src/Trash/ResourcePaths.cs +++ b/src/Trash/ResourcePaths.cs @@ -5,4 +5,5 @@ namespace Trash; public class ResourcePaths : IResourcePaths { public string RepoPath => AppPaths.RepoDirectory; + public string SettingsPath => AppPaths.DefaultSettingsPath; } diff --git a/src/TrashLib.Tests/Cache/ServiceCacheTest.cs b/src/TrashLib.Tests/Cache/ServiceCacheTest.cs index 7ce0f305..ff1381df 100644 --- a/src/TrashLib.Tests/Cache/ServiceCacheTest.cs +++ b/src/TrashLib.Tests/Cache/ServiceCacheTest.cs @@ -10,7 +10,6 @@ using NUnit.Framework; using Serilog; using TestLibrary.NSubstitute; using TrashLib.Cache; -using TrashLib.Config; using TrashLib.Config.Services; namespace TrashLib.Tests.Cache; diff --git a/src/TrashLib.Tests/Config/Settings/SettingsPersisterTest.cs b/src/TrashLib.Tests/Config/Settings/SettingsPersisterTest.cs new file mode 100644 index 00000000..8f0e8545 --- /dev/null +++ b/src/TrashLib.Tests/Config/Settings/SettingsPersisterTest.cs @@ -0,0 +1,69 @@ +using System.IO.Abstractions.TestingHelpers; +using AutoFixture.NUnit3; +using FluentAssertions; +using NSubstitute; +using NUnit.Framework; +using TestLibrary.AutoFixture; +using TrashLib.Config; +using TrashLib.Config.Settings; +using TrashLib.Radarr.Config; +using YamlDotNet.Serialization; + +namespace TrashLib.Tests.Config.Settings; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class SettingsPersisterTest +{ + [Test, AutoMockData] + public void Load_should_create_settings_file_if_not_exists( + [Frozen(Matching.ImplementedInterfaces)] MockFileSystem fileSystem, + [Frozen] IResourcePaths paths, + SettingsPersister sut) + { + paths.SettingsPath.Returns("test_path"); + + sut.Load(); + + fileSystem.AllFiles.Should().ContainSingle(x => x.EndsWith(paths.SettingsPath)); + } + + [Test, AutoMockData] + public void Load_defaults_when_file_does_not_exist( + [Frozen(Matching.ImplementedInterfaces)] MockFileSystem fileSystem, + [Frozen(Matching.ImplementedInterfaces)] YamlSerializerFactory serializerFactory, + [Frozen(Matching.ImplementedInterfaces)] SettingsProvider settingsProvider, + [Frozen] IResourcePaths paths, + SettingsPersister sut) + { + paths.SettingsPath.Returns("test_path"); + + sut.Load(); + + var expectedSettings = new SettingsValues(); + settingsProvider.Settings.Should().BeEquivalentTo(expectedSettings); + } + + [Test, AutoMockData] + public void Load_data_correctly_when_file_exists( + [Frozen(Matching.ImplementedInterfaces)] MockFileSystem fileSystem, + [Frozen] IYamlSerializerFactory serializerFactory, + [Frozen] IResourcePaths paths, + SettingsPersister sut) + { + // For this test, it doesn't really matter if the YAML data matches what SettingsValue expects; + // this test only ensures that the data deserialized is from the actual correct file. + var expectedYamlData = @" +repository: + clone_url: http://the_url.com +"; + var deserializer = Substitute.For(); + serializerFactory.CreateDeserializer().Returns(deserializer); + paths.SettingsPath.Returns("test_path"); + fileSystem.AddFile(paths.SettingsPath, new MockFileData(expectedYamlData)); + + sut.Load(); + + deserializer.Received().Deserialize(expectedYamlData); + } +} diff --git a/src/TrashLib.Tests/Config/Settings/SettingsProviderTest.cs b/src/TrashLib.Tests/Config/Settings/SettingsProviderTest.cs new file mode 100644 index 00000000..b0a2dec4 --- /dev/null +++ b/src/TrashLib.Tests/Config/Settings/SettingsProviderTest.cs @@ -0,0 +1,19 @@ +using FluentAssertions; +using NUnit.Framework; +using TestLibrary.AutoFixture; +using TrashLib.Config.Settings; + +namespace TrashLib.Tests.Config.Settings; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class SettingsProviderTest +{ + [Test, AutoMockData] + public void Property_returns_same_value_from_set_method(SettingsProvider sut) + { + var settings = new SettingsValues(); + sut.UseSettings(settings); + sut.Settings.Should().Be(settings); + } +} diff --git a/src/TrashLib.Tests/Radarr/CustomFormat/Processors/PersistenceProcessorTest.cs b/src/TrashLib.Tests/Radarr/CustomFormat/Processors/PersistenceProcessorTest.cs index b3e96172..048b2938 100644 --- a/src/TrashLib.Tests/Radarr/CustomFormat/Processors/PersistenceProcessorTest.cs +++ b/src/TrashLib.Tests/Radarr/CustomFormat/Processors/PersistenceProcessorTest.cs @@ -4,7 +4,6 @@ using System.Collections.ObjectModel; using Newtonsoft.Json.Linq; using NSubstitute; using NUnit.Framework; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.Config; using TrashLib.Radarr.CustomFormat.Api; diff --git a/src/TrashLib/Cache/ServiceCache.cs b/src/TrashLib/Cache/ServiceCache.cs index d9295462..936b8446 100644 --- a/src/TrashLib/Cache/ServiceCache.cs +++ b/src/TrashLib/Cache/ServiceCache.cs @@ -9,7 +9,6 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using Serilog; -using TrashLib.Config; using TrashLib.Config.Services; namespace TrashLib.Cache; diff --git a/src/TrashLib/Config/ConfigAutofacModule.cs b/src/TrashLib/Config/ConfigAutofacModule.cs index e4f3c491..fa3b1f28 100644 --- a/src/TrashLib/Config/ConfigAutofacModule.cs +++ b/src/TrashLib/Config/ConfigAutofacModule.cs @@ -2,6 +2,7 @@ using System.Reflection; using Autofac; using FluentValidation; using TrashLib.Config.Services; +using TrashLib.Config.Settings; using Module = Autofac.Module; namespace TrashLib.Config; @@ -10,14 +11,13 @@ public class ConfigAutofacModule : Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterType() - .As() - .SingleInstance(); - builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .AsClosedTypesOf(typeof(IValidator<>)) .AsImplementedInterfaces(); - builder.RegisterType().As(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As(); + builder.RegisterType().As(); } } diff --git a/src/TrashLib/Config/Settings/ISettingsPersister.cs b/src/TrashLib/Config/Settings/ISettingsPersister.cs new file mode 100644 index 00000000..75706238 --- /dev/null +++ b/src/TrashLib/Config/Settings/ISettingsPersister.cs @@ -0,0 +1,6 @@ +namespace TrashLib.Config.Settings; + +public interface ISettingsPersister +{ + void Load(); +} diff --git a/src/TrashLib/Config/Settings/ISettingsProvider.cs b/src/TrashLib/Config/Settings/ISettingsProvider.cs new file mode 100644 index 00000000..fa2c1187 --- /dev/null +++ b/src/TrashLib/Config/Settings/ISettingsProvider.cs @@ -0,0 +1,7 @@ +namespace TrashLib.Config.Settings; + +public interface ISettingsProvider +{ + SettingsValues Settings { get; } + void UseSettings(SettingsValues settings); +} diff --git a/src/TrashLib/Config/Settings/SettingsPersister.cs b/src/TrashLib/Config/Settings/SettingsPersister.cs new file mode 100644 index 00000000..746ed8b6 --- /dev/null +++ b/src/TrashLib/Config/Settings/SettingsPersister.cs @@ -0,0 +1,51 @@ +using System.IO.Abstractions; +using TrashLib.Radarr.Config; + +namespace TrashLib.Config.Settings; + +public class SettingsPersister : ISettingsPersister +{ + private readonly IResourcePaths _paths; + private readonly ISettingsProvider _settingsProvider; + private readonly IYamlSerializerFactory _serializerFactory; + private readonly IFileSystem _fileSystem; + + public SettingsPersister( + IResourcePaths paths, + ISettingsProvider settingsProvider, + IYamlSerializerFactory serializerFactory, + IFileSystem fileSystem) + { + _paths = paths; + _settingsProvider = settingsProvider; + _serializerFactory = serializerFactory; + _fileSystem = fileSystem; + } + + public void Load() + { + var deserializer = _serializerFactory.CreateDeserializer(); + var settings = deserializer.Deserialize(LoadOrCreateSettingsFile()) ?? new SettingsValues(); + _settingsProvider.UseSettings(settings); + } + + private string LoadOrCreateSettingsFile() + { + if (!_fileSystem.File.Exists(_paths.SettingsPath)) + { + CreateDefaultSettingsFile(); + } + + return _fileSystem.File.ReadAllText(_paths.SettingsPath); + } + + private void CreateDefaultSettingsFile() + { + const string fileData = + "# Edit this file to customize the behavior of Trash Updater beyond its defaults\n" + + "# For the settings file reference guide, visit the link to the wiki below:\n" + + "# https://github.com/rcdailey/trash-updater/wiki/Settings-Reference\n"; + + _fileSystem.File.WriteAllText(_paths.SettingsPath, fileData); + } +} diff --git a/src/TrashLib/Config/Settings/SettingsProvider.cs b/src/TrashLib/Config/Settings/SettingsProvider.cs new file mode 100644 index 00000000..eac5e5fc --- /dev/null +++ b/src/TrashLib/Config/Settings/SettingsProvider.cs @@ -0,0 +1,11 @@ +namespace TrashLib.Config.Settings; + +public class SettingsProvider : ISettingsProvider +{ + public SettingsValues Settings { get; private set; } = new(); + + public void UseSettings(SettingsValues settings) + { + Settings = settings; + } +} diff --git a/src/TrashLib/Config/Settings/SettingsValues.cs b/src/TrashLib/Config/Settings/SettingsValues.cs new file mode 100644 index 00000000..7f1bef5d --- /dev/null +++ b/src/TrashLib/Config/Settings/SettingsValues.cs @@ -0,0 +1,11 @@ +namespace TrashLib.Config.Settings; + +public record TrashRepository +{ + public string CloneUrl { get; init; } = "https://github.com/TRaSH-/Guides.git"; +} + +public record SettingsValues +{ + public TrashRepository Repository { get; init; } = new(); +} diff --git a/src/TrashLib/Radarr/Config/IResourcePaths.cs b/src/TrashLib/Radarr/Config/IResourcePaths.cs index 298b0242..5a071f42 100644 --- a/src/TrashLib/Radarr/Config/IResourcePaths.cs +++ b/src/TrashLib/Radarr/Config/IResourcePaths.cs @@ -3,4 +3,5 @@ namespace TrashLib.Radarr.Config; public interface IResourcePaths { string RepoPath { get; } + string SettingsPath { get; } } diff --git a/src/TrashLib/Radarr/Config/RadarrConfiguration.cs b/src/TrashLib/Radarr/Config/RadarrConfiguration.cs index 2282a671..15783829 100644 --- a/src/TrashLib/Radarr/Config/RadarrConfiguration.cs +++ b/src/TrashLib/Radarr/Config/RadarrConfiguration.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using JetBrains.Annotations; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.QualityDefinition; diff --git a/src/TrashLib/Radarr/CustomFormat/Api/CustomFormatService.cs b/src/TrashLib/Radarr/CustomFormat/Api/CustomFormatService.cs index cce5d3e2..845ea2bb 100644 --- a/src/TrashLib/Radarr/CustomFormat/Api/CustomFormatService.cs +++ b/src/TrashLib/Radarr/CustomFormat/Api/CustomFormatService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Flurl.Http; using Newtonsoft.Json.Linq; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.CustomFormat.Models; diff --git a/src/TrashLib/Radarr/CustomFormat/Api/QualityProfileService.cs b/src/TrashLib/Radarr/CustomFormat/Api/QualityProfileService.cs index 090b8fdc..101ac97e 100644 --- a/src/TrashLib/Radarr/CustomFormat/Api/QualityProfileService.cs +++ b/src/TrashLib/Radarr/CustomFormat/Api/QualityProfileService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Flurl.Http; using Newtonsoft.Json.Linq; -using TrashLib.Config; using TrashLib.Config.Services; namespace TrashLib.Radarr.CustomFormat.Api; diff --git a/src/TrashLib/Radarr/CustomFormat/Guide/LocalRepoCustomFormatJsonParser.cs b/src/TrashLib/Radarr/CustomFormat/Guide/LocalRepoCustomFormatJsonParser.cs index 9960ccd0..7f0c3bcd 100644 --- a/src/TrashLib/Radarr/CustomFormat/Guide/LocalRepoCustomFormatJsonParser.cs +++ b/src/TrashLib/Radarr/CustomFormat/Guide/LocalRepoCustomFormatJsonParser.cs @@ -4,6 +4,8 @@ using System.IO.Abstractions; using System.Linq; using System.Threading.Tasks; using LibGit2Sharp; +using Serilog; +using TrashLib.Config.Settings; using TrashLib.Radarr.Config; namespace TrashLib.Radarr.CustomFormat.Guide @@ -11,48 +13,70 @@ namespace TrashLib.Radarr.CustomFormat.Guide internal class LocalRepoCustomFormatJsonParser : IRadarrGuideService { private readonly IFileSystem _fileSystem; + private readonly ISettingsProvider _settings; + private readonly ILogger _log; private readonly string _repoPath; - public LocalRepoCustomFormatJsonParser(IFileSystem fileSystem, IResourcePaths paths) + public LocalRepoCustomFormatJsonParser( + IFileSystem fileSystem, + IResourcePaths paths, + ISettingsProvider settings, + ILogger log) { _fileSystem = fileSystem; + _settings = settings; + _log = log; _repoPath = paths.RepoPath; } public async Task> GetCustomFormatJsonAsync() { - await Task.Run(() => + CloneOrUpdateGitRepo(); + + var jsonDir = Path.Combine(_repoPath, "docs/json/radarr"); + var tasks = _fileSystem.Directory.GetFiles(jsonDir, "*.json") + .Select(async f => await _fileSystem.File.ReadAllTextAsync(f)); + + return await Task.WhenAll(tasks); + } + + private void CloneOrUpdateGitRepo() + { + var cloneUrl = _settings.Settings.Repository.CloneUrl; + + if (!Repository.IsValid(_repoPath)) { - if (!Repository.IsValid(_repoPath)) + if (_fileSystem.Directory.Exists(_repoPath)) { - if (_fileSystem.Directory.Exists(_repoPath)) - { - _fileSystem.Directory.Delete(_repoPath, true); - } - - Repository.Clone("https://github.com/TRaSH-/Guides.git", _repoPath, new CloneOptions - { - RecurseSubmodules = false - }); + _fileSystem.Directory.Delete(_repoPath, true); } - using var repo = new Repository(_repoPath); - Commands.Checkout(repo, "master", new CheckoutOptions + Repository.Clone(cloneUrl, _repoPath, new CloneOptions { - CheckoutModifiers = CheckoutModifiers.Force + RecurseSubmodules = false }); + } - var origin = repo.Network.Remotes["origin"]; - Commands.Fetch(repo, origin.Name, origin.FetchRefSpecs.Select(s => s.Specification), null, ""); - - repo.Reset(ResetMode.Hard, repo.Branches["origin/master"].Tip); + using var repo = new Repository(_repoPath); + Commands.Checkout(repo, "master", new CheckoutOptions + { + CheckoutModifiers = CheckoutModifiers.Force }); - var jsonDir = Path.Combine(_repoPath, "docs/json/radarr"); - var tasks = _fileSystem.Directory.GetFiles(jsonDir, "*.json") - .Select(async f => await _fileSystem.File.ReadAllTextAsync(f)); + var origin = repo.Network.Remotes["origin"]; + if (origin.Url != cloneUrl) + { + _log.Debug( + "Origin's URL ({OriginUrl}) does not match the clone URL from settings ({CloneUrl}) and will be updated", + origin.Url, cloneUrl); - return await Task.WhenAll(tasks); + repo.Network.Remotes.Update("origin", updater => updater.Url = cloneUrl); + origin = repo.Network.Remotes["origin"]; + } + + Commands.Fetch(repo, origin.Name, origin.FetchRefSpecs.Select(s => s.Specification), null, ""); + + repo.Reset(ResetMode.Hard, repo.Branches["origin/master"].Tip); } } } diff --git a/src/TrashLib/Radarr/CustomFormat/Processors/PersistenceProcessor.cs b/src/TrashLib/Radarr/CustomFormat/Processors/PersistenceProcessor.cs index 68cf1ab4..aab62e7a 100644 --- a/src/TrashLib/Radarr/CustomFormat/Processors/PersistenceProcessor.cs +++ b/src/TrashLib/Radarr/CustomFormat/Processors/PersistenceProcessor.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.Config; using TrashLib.Radarr.CustomFormat.Api; diff --git a/src/TrashLib/Radarr/QualityDefinition/Api/QualityDefinitionService.cs b/src/TrashLib/Radarr/QualityDefinition/Api/QualityDefinitionService.cs index 1d2ae8cb..26fcfe57 100644 --- a/src/TrashLib/Radarr/QualityDefinition/Api/QualityDefinitionService.cs +++ b/src/TrashLib/Radarr/QualityDefinition/Api/QualityDefinitionService.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Flurl.Http; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.QualityDefinition.Api.Objects; diff --git a/src/TrashLib/Radarr/RadarrAutofacModule.cs b/src/TrashLib/Radarr/RadarrAutofacModule.cs index 41d4baa0..8fbbb509 100644 --- a/src/TrashLib/Radarr/RadarrAutofacModule.cs +++ b/src/TrashLib/Radarr/RadarrAutofacModule.cs @@ -1,6 +1,5 @@ using Autofac; using Autofac.Extras.AggregateService; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Radarr.Config; using TrashLib.Radarr.CustomFormat; diff --git a/src/TrashLib/Sonarr/Api/SonarrApi.cs b/src/TrashLib/Sonarr/Api/SonarrApi.cs index 7c88a041..c59addd6 100644 --- a/src/TrashLib/Sonarr/Api/SonarrApi.cs +++ b/src/TrashLib/Sonarr/Api/SonarrApi.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Flurl.Http; using Newtonsoft.Json.Linq; using Serilog; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Extensions; using TrashLib.Sonarr.Api.Objects; diff --git a/src/TrashLib/Sonarr/Config/SonarrConfiguration.cs b/src/TrashLib/Sonarr/Config/SonarrConfiguration.cs index c6249817..7d8a4df0 100644 --- a/src/TrashLib/Sonarr/Config/SonarrConfiguration.cs +++ b/src/TrashLib/Sonarr/Config/SonarrConfiguration.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using TrashLib.Config; using TrashLib.Config.Services; using TrashLib.Sonarr.QualityDefinition; using TrashLib.Sonarr.ReleaseProfile; diff --git a/src/TrashLib/Sonarr/SonarrCompatibility.cs b/src/TrashLib/Sonarr/SonarrCompatibility.cs index 1a4ded28..3ea8eaeb 100644 --- a/src/TrashLib/Sonarr/SonarrCompatibility.cs +++ b/src/TrashLib/Sonarr/SonarrCompatibility.cs @@ -2,7 +2,6 @@ using System; using System.Reactive.Concurrency; using System.Reactive.Linq; using Flurl.Http; -using TrashLib.Config; using TrashLib.Config.Services; namespace TrashLib.Sonarr; diff --git a/wiki/Home.md b/wiki/Home.md index 9c73dd0d..03ecdc1c 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -2,6 +2,7 @@ Pages of Interest: - [[Command Line Reference]] - [[Configuration Reference]] +- [[Settings Reference]] - [[TRaSH Guide Structural Guidelines]] See the "Pages" list on the right side of this page for the complete list of wiki pages. diff --git a/wiki/Settings-Reference.md b/wiki/Settings-Reference.md new file mode 100644 index 00000000..32f05916 --- /dev/null +++ b/wiki/Settings-Reference.md @@ -0,0 +1,36 @@ +This page contains the YAML reference for `settings.yml`. This file is located in the following +locations depending on your platform: + +| Platform | Location | +| -------- | ---------------------------------------------------------- | +| Windows | `%APPDATA%\trash-updater\settings.yml` | +| Linux | `~/.config/trash-updater/settings.yml` | +| MacOS | `~/Library/Application Support/trash-updater/settings.yml` | + +Settings in this file affect the behavior of Trash Updater regardless of instance-specific +configuration for Radarr and Sonarr. + +If this file does not exist, Trash Updater will create it for you. Starting out, this file will be +empty and default behavior will be used. There is absolutely no need to touch this file unless you +have a specific reason to. It is recommended that you only add the specific properties for the +customizations you need and leave the rest alone. + +# YAML Reference + +Table of Contents + +- [Repository Settings](#repository-settings) + +## Repository Settings + +```yml +repository: + clone_url: https://github.com/TRaSH-/Guides.git +``` + +- `clone_url`
+ A URL compatible with `git clone` that is used to clone the [Trash Guides + repository](official_repo). This setting exists for enthusiasts that may want to instead have + Trash Updater pull data from a fork instead of the official repository. + +[official_repo]: https://github.com/TRaSH-/Guides