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.
pull/47/head
Robert Dailey 2 years ago
parent b6b6ebda9e
commit 2fe29f3b16

@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [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 ### Fixed
- Remove `System.Reactive.xml` from the published ZIP files. - Remove `System.Reactive.xml` from the published ZIP files.

@ -38,10 +38,11 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition="$(ProjectName.EndsWith('.Tests'))"> <ItemGroup Condition="$(ProjectName.EndsWith('.Tests'))">
<PackageReference Include="AutofacContrib.NSubstitute" PrivateAssets="All" />
<PackageReference Include="AutoFixture" PrivateAssets="All" /> <PackageReference Include="AutoFixture" PrivateAssets="All" />
<PackageReference Include="AutoFixture.AutoNSubstitute" PrivateAssets="All" /> <PackageReference Include="AutoFixture.AutoNSubstitute" PrivateAssets="All" />
<PackageReference Include="AutoFixture.NUnit3" PrivateAssets="All" /> <PackageReference Include="AutoFixture.NUnit3" PrivateAssets="All" />
<PackageReference Include="AutofacContrib.NSubstitute" PrivateAssets="All" /> <PackageReference Include="coverlet.collector" PrivateAssets="All" />
<PackageReference Include="FluentAssertions" PrivateAssets="All" /> <PackageReference Include="FluentAssertions" PrivateAssets="All" />
<PackageReference Include="FluentAssertions.Json" PrivateAssets="All" /> <PackageReference Include="FluentAssertions.Json" PrivateAssets="All" />
<PackageReference Include="GitHubActionsTestLogger" PrivateAssets="All" /> <PackageReference Include="GitHubActionsTestLogger" PrivateAssets="All" />
@ -53,7 +54,7 @@
<PackageReference Include="NUnit3TestAdapter" PrivateAssets="All" /> <PackageReference Include="NUnit3TestAdapter" PrivateAssets="All" />
<PackageReference Include="Serilog.Sinks.NUnit" PrivateAssets="All" /> <PackageReference Include="Serilog.Sinks.NUnit" PrivateAssets="All" />
<PackageReference Include="Serilog.Sinks.TestCorrelator" PrivateAssets="All" /> <PackageReference Include="Serilog.Sinks.TestCorrelator" PrivateAssets="All" />
<PackageReference Include="coverlet.collector" PrivateAssets="All" /> <PackageReference Include="System.IO.Abstractions.TestingHelpers" PrivateAssets="All" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="$(ProjectName.EndsWith('.Tests'))"> <ItemGroup Condition="$(ProjectName.EndsWith('.Tests'))">

@ -36,6 +36,7 @@
<PackageReference Update="Serilog.Sinks.TestCorrelator" Version="3.*" /> <PackageReference Update="Serilog.Sinks.TestCorrelator" Version="3.*" />
<PackageReference Update="System.Data.HashFunction.FNV" Version="2.*" /> <PackageReference Update="System.Data.HashFunction.FNV" Version="2.*" />
<PackageReference Update="System.IO.Abstractions" Version="16.*" /> <PackageReference Update="System.IO.Abstractions" Version="16.*" />
<PackageReference Update="System.IO.Abstractions.TestingHelpers" Version="16.*" />
<PackageReference Update="System.Reactive" Version="5.*" /> <PackageReference Update="System.Reactive" Version="5.*" />
<PackageReference Update="YamlDotNet" Version="11.*" /> <PackageReference Update="YamlDotNet" Version="11.*" />
</ItemGroup> </ItemGroup>

@ -1,4 +1,3 @@
using System;
using System.Reflection; using System.Reflection;
using Autofac; using Autofac;
using AutoFixture.Kernel; using AutoFixture.Kernel;

@ -3,7 +3,7 @@ using AutoFixture.NUnit3;
namespace TestLibrary.AutoFixture; namespace TestLibrary.AutoFixture;
public class InlineAutoMockDataAttribute : InlineAutoDataAttribute public sealed class InlineAutoMockDataAttribute : InlineAutoDataAttribute
{ {
[SuppressMessage("Design", "CA1019", MessageId = "Define accessors for attribute arguments", [SuppressMessage("Design", "CA1019", MessageId = "Define accessors for attribute arguments",
Justification = "The parameter is forwarded to the base class and not used directly")] Justification = "The parameter is forwarded to the base class and not used directly")]

@ -42,7 +42,7 @@ public class ConfigurationLoaderTest
{ {
var builder = new ContainerBuilder(); var builder = new ContainerBuilder();
builder.RegisterType<DefaultObjectFactory>().As<IObjectFactory>(); builder.RegisterType<DefaultObjectFactory>().As<IObjectFactory>();
builder.RegisterType<YamlDeserializerFactory>().As<IYamlDeserializerFactory>(); builder.RegisterType<YamlSerializerFactory>().As<IYamlSerializerFactory>();
return builder.Build(); return builder.Build();
} }

@ -10,6 +10,8 @@ internal static class AppPaths
public static string DefaultConfigPath { get; } = Path.Combine(AppContext.BaseDirectory, "trash.yml"); 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 LogDirectory { get; } = Path.Combine(AppDataPath, "logs");
public static string RepoDirectory { get; } = Path.Combine(AppDataPath, "repo"); public static string RepoDirectory { get; } = Path.Combine(AppDataPath, "repo");

@ -6,8 +6,8 @@ using Flurl.Http;
using JetBrains.Annotations; using JetBrains.Annotations;
using Serilog; using Serilog;
using Serilog.Core; using Serilog.Core;
using Trash.Command.Helpers;
using Trash.Config; using Trash.Config;
using TrashLib.Config.Settings;
using TrashLib.Radarr.Config; using TrashLib.Radarr.Config;
using TrashLib.Radarr.CustomFormat; using TrashLib.Radarr.CustomFormat;
using TrashLib.Radarr.QualityDefinition; using TrashLib.Radarr.QualityDefinition;
@ -27,10 +27,11 @@ public class RadarrCommand : ServiceCommand
ILogger log, ILogger log,
LoggingLevelSwitch loggingLevelSwitch, LoggingLevelSwitch loggingLevelSwitch,
ILogJanitor logJanitor, ILogJanitor logJanitor,
ISettingsPersister settingsPersister,
IConfigurationLoader<RadarrConfiguration> configLoader, IConfigurationLoader<RadarrConfiguration> configLoader,
Func<IRadarrQualityDefinitionUpdater> qualityUpdaterFactory, Func<IRadarrQualityDefinitionUpdater> qualityUpdaterFactory,
Func<ICustomFormatUpdater> customFormatUpdaterFactory) Func<ICustomFormatUpdater> customFormatUpdaterFactory)
: base(log, loggingLevelSwitch, logJanitor) : base(log, loggingLevelSwitch, logJanitor, settingsPersister)
{ {
_log = log; _log = log;
_configLoader = configLoader; _configLoader = configLoader;

@ -12,6 +12,7 @@ using Newtonsoft.Json;
using Serilog; using Serilog;
using Serilog.Core; using Serilog.Core;
using Serilog.Events; using Serilog.Events;
using TrashLib.Config.Settings;
using TrashLib.Extensions; using TrashLib.Extensions;
using YamlDotNet.Core; using YamlDotNet.Core;
@ -22,20 +23,24 @@ public abstract class ServiceCommand : ICommand, IServiceCommand
private readonly ILogger _log; private readonly ILogger _log;
private readonly LoggingLevelSwitch _loggingLevelSwitch; private readonly LoggingLevelSwitch _loggingLevelSwitch;
private readonly ILogJanitor _logJanitor; private readonly ILogJanitor _logJanitor;
private readonly ISettingsPersister _settingsPersister;
protected ServiceCommand( protected ServiceCommand(
ILogger log, ILogger log,
LoggingLevelSwitch loggingLevelSwitch, LoggingLevelSwitch loggingLevelSwitch,
ILogJanitor logJanitor) ILogJanitor logJanitor,
ISettingsPersister settingsPersister)
{ {
_loggingLevelSwitch = loggingLevelSwitch; _loggingLevelSwitch = loggingLevelSwitch;
_logJanitor = logJanitor; _logJanitor = logJanitor;
_settingsPersister = settingsPersister;
_log = log; _log = log;
} }
public async ValueTask ExecuteAsync(IConsole console) public async ValueTask ExecuteAsync(IConsole console)
{ {
SetupLogging(); SetupLogging();
LoadSettings();
SetupHttp(); SetupHttp();
try try
@ -65,6 +70,11 @@ public abstract class ServiceCommand : ICommand, IServiceCommand
} }
} }
private void LoadSettings()
{
_settingsPersister.Load();
}
[CommandOption("preview", 'p', Description = [CommandOption("preview", 'p', Description =
"Only display the processed markdown results without making any API calls.")] "Only display the processed markdown results without making any API calls.")]
public bool Preview { get; [UsedImplicitly] set; } = false; public bool Preview { get; [UsedImplicitly] set; } = false;

@ -6,8 +6,8 @@ using Flurl.Http;
using JetBrains.Annotations; using JetBrains.Annotations;
using Serilog; using Serilog;
using Serilog.Core; using Serilog.Core;
using Trash.Command.Helpers;
using Trash.Config; using Trash.Config;
using TrashLib.Config.Settings;
using TrashLib.Sonarr.Config; using TrashLib.Sonarr.Config;
using TrashLib.Sonarr.QualityDefinition; using TrashLib.Sonarr.QualityDefinition;
using TrashLib.Sonarr.ReleaseProfile; using TrashLib.Sonarr.ReleaseProfile;
@ -27,10 +27,11 @@ public class SonarrCommand : ServiceCommand
ILogger log, ILogger log,
LoggingLevelSwitch loggingLevelSwitch, LoggingLevelSwitch loggingLevelSwitch,
ILogJanitor logJanitor, ILogJanitor logJanitor,
ISettingsPersister settingsPersister,
IConfigurationLoader<SonarrConfiguration> configLoader, IConfigurationLoader<SonarrConfiguration> configLoader,
Func<IReleaseProfileUpdater> profileUpdaterFactory, Func<IReleaseProfileUpdater> profileUpdaterFactory,
Func<ISonarrQualityDefinitionUpdater> qualityUpdaterFactory) Func<ISonarrQualityDefinitionUpdater> qualityUpdaterFactory)
: base(log, loggingLevelSwitch, logJanitor) : base(log, loggingLevelSwitch, logJanitor, settingsPersister)
{ {
_log = log; _log = log;
_configLoader = configLoader; _configLoader = configLoader;

@ -22,13 +22,13 @@ public class ConfigurationLoader<T> : IConfigurationLoader<T>
public ConfigurationLoader( public ConfigurationLoader(
IConfigurationProvider configProvider, IConfigurationProvider configProvider,
IFileSystem fileSystem, IFileSystem fileSystem,
IYamlDeserializerFactory yamlFactory, IYamlSerializerFactory yamlFactory,
IValidator<T> validator) IValidator<T> validator)
{ {
_configProvider = configProvider; _configProvider = configProvider;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_validator = validator; _validator = validator;
_deserializer = yamlFactory.Create(); _deserializer = yamlFactory.CreateDeserializer();
} }
public IEnumerable<T> Load(string propertyName, string configSection) public IEnumerable<T> Load(string propertyName, string configSection)

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
namespace Trash.Config; namespace Trash.Config;

@ -5,4 +5,5 @@ namespace Trash;
public class ResourcePaths : IResourcePaths public class ResourcePaths : IResourcePaths
{ {
public string RepoPath => AppPaths.RepoDirectory; public string RepoPath => AppPaths.RepoDirectory;
public string SettingsPath => AppPaths.DefaultSettingsPath;
} }

@ -10,7 +10,6 @@ using NUnit.Framework;
using Serilog; using Serilog;
using TestLibrary.NSubstitute; using TestLibrary.NSubstitute;
using TrashLib.Cache; using TrashLib.Cache;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
namespace TrashLib.Tests.Cache; namespace TrashLib.Tests.Cache;

@ -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<IDeserializer>();
serializerFactory.CreateDeserializer().Returns(deserializer);
paths.SettingsPath.Returns("test_path");
fileSystem.AddFile(paths.SettingsPath, new MockFileData(expectedYamlData));
sut.Load();
deserializer.Received().Deserialize<SettingsValues>(expectedYamlData);
}
}

@ -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);
}
}

@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.Config; using TrashLib.Radarr.Config;
using TrashLib.Radarr.CustomFormat.Api; using TrashLib.Radarr.CustomFormat.Api;

@ -9,7 +9,6 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using Serilog; using Serilog;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
namespace TrashLib.Cache; namespace TrashLib.Cache;

@ -2,6 +2,7 @@ using System.Reflection;
using Autofac; using Autofac;
using FluentValidation; using FluentValidation;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Config.Settings;
using Module = Autofac.Module; using Module = Autofac.Module;
namespace TrashLib.Config; namespace TrashLib.Config;
@ -10,14 +11,13 @@ public class ConfigAutofacModule : Module
{ {
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)
{ {
builder.RegisterType<ConfigurationProvider>()
.As<IConfigurationProvider>()
.SingleInstance();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(IValidator<>)) .AsClosedTypesOf(typeof(IValidator<>))
.AsImplementedInterfaces(); .AsImplementedInterfaces();
builder.RegisterType<YamlDeserializerFactory>().As<IYamlDeserializerFactory>(); builder.RegisterType<ConfigurationProvider>().As<IConfigurationProvider>().SingleInstance();
builder.RegisterType<SettingsProvider>().As<ISettingsProvider>().SingleInstance();
builder.RegisterType<YamlSerializerFactory>().As<IYamlSerializerFactory>();
builder.RegisterType<SettingsPersister>().As<ISettingsPersister>();
} }
} }

@ -0,0 +1,6 @@
namespace TrashLib.Config.Settings;
public interface ISettingsPersister
{
void Load();
}

@ -0,0 +1,7 @@
namespace TrashLib.Config.Settings;
public interface ISettingsProvider
{
SettingsValues Settings { get; }
void UseSettings(SettingsValues settings);
}

@ -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<SettingsValues?>(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);
}
}

@ -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;
}
}

@ -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();
}

@ -3,4 +3,5 @@ namespace TrashLib.Radarr.Config;
public interface IResourcePaths public interface IResourcePaths
{ {
string RepoPath { get; } string RepoPath { get; }
string SettingsPath { get; }
} }

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.QualityDefinition; using TrashLib.Radarr.QualityDefinition;

@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flurl.Http; using Flurl.Http;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.CustomFormat.Models; using TrashLib.Radarr.CustomFormat.Models;

@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flurl.Http; using Flurl.Http;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
namespace TrashLib.Radarr.CustomFormat.Api; namespace TrashLib.Radarr.CustomFormat.Api;

@ -4,6 +4,8 @@ using System.IO.Abstractions;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using LibGit2Sharp; using LibGit2Sharp;
using Serilog;
using TrashLib.Config.Settings;
using TrashLib.Radarr.Config; using TrashLib.Radarr.Config;
namespace TrashLib.Radarr.CustomFormat.Guide namespace TrashLib.Radarr.CustomFormat.Guide
@ -11,48 +13,70 @@ namespace TrashLib.Radarr.CustomFormat.Guide
internal class LocalRepoCustomFormatJsonParser : IRadarrGuideService internal class LocalRepoCustomFormatJsonParser : IRadarrGuideService
{ {
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ISettingsProvider _settings;
private readonly ILogger _log;
private readonly string _repoPath; private readonly string _repoPath;
public LocalRepoCustomFormatJsonParser(IFileSystem fileSystem, IResourcePaths paths) public LocalRepoCustomFormatJsonParser(
IFileSystem fileSystem,
IResourcePaths paths,
ISettingsProvider settings,
ILogger log)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_settings = settings;
_log = log;
_repoPath = paths.RepoPath; _repoPath = paths.RepoPath;
} }
public async Task<IEnumerable<string>> GetCustomFormatJsonAsync() public async Task<IEnumerable<string>> 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);
{
_fileSystem.Directory.Delete(_repoPath, true);
}
Repository.Clone("https://github.com/TRaSH-/Guides.git", _repoPath, new CloneOptions
{
RecurseSubmodules = false
});
} }
using var repo = new Repository(_repoPath); Repository.Clone(cloneUrl, _repoPath, new CloneOptions
Commands.Checkout(repo, "master", new CheckoutOptions
{ {
CheckoutModifiers = CheckoutModifiers.Force RecurseSubmodules = false
}); });
}
var origin = repo.Network.Remotes["origin"]; using var repo = new Repository(_repoPath);
Commands.Fetch(repo, origin.Name, origin.FetchRefSpecs.Select(s => s.Specification), null, ""); Commands.Checkout(repo, "master", new CheckoutOptions
{
repo.Reset(ResetMode.Hard, repo.Branches["origin/master"].Tip); CheckoutModifiers = CheckoutModifiers.Force
}); });
var jsonDir = Path.Combine(_repoPath, "docs/json/radarr"); var origin = repo.Network.Remotes["origin"];
var tasks = _fileSystem.Directory.GetFiles(jsonDir, "*.json") if (origin.Url != cloneUrl)
.Select(async f => await _fileSystem.File.ReadAllTextAsync(f)); {
_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);
} }
} }
} }

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.Config; using TrashLib.Radarr.Config;
using TrashLib.Radarr.CustomFormat.Api; using TrashLib.Radarr.CustomFormat.Api;

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flurl.Http; using Flurl.Http;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.QualityDefinition.Api.Objects; using TrashLib.Radarr.QualityDefinition.Api.Objects;

@ -1,6 +1,5 @@
using Autofac; using Autofac;
using Autofac.Extras.AggregateService; using Autofac.Extras.AggregateService;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Radarr.Config; using TrashLib.Radarr.Config;
using TrashLib.Radarr.CustomFormat; using TrashLib.Radarr.CustomFormat;

@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Flurl.Http; using Flurl.Http;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Serilog; using Serilog;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Extensions; using TrashLib.Extensions;
using TrashLib.Sonarr.Api.Objects; using TrashLib.Sonarr.Api.Objects;

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
using TrashLib.Sonarr.QualityDefinition; using TrashLib.Sonarr.QualityDefinition;
using TrashLib.Sonarr.ReleaseProfile; using TrashLib.Sonarr.ReleaseProfile;

@ -2,7 +2,6 @@ using System;
using System.Reactive.Concurrency; using System.Reactive.Concurrency;
using System.Reactive.Linq; using System.Reactive.Linq;
using Flurl.Http; using Flurl.Http;
using TrashLib.Config;
using TrashLib.Config.Services; using TrashLib.Config.Services;
namespace TrashLib.Sonarr; namespace TrashLib.Sonarr;

@ -2,6 +2,7 @@ Pages of Interest:
- [[Command Line Reference]] - [[Command Line Reference]]
- [[Configuration Reference]] - [[Configuration Reference]]
- [[Settings Reference]]
- [[TRaSH Guide Structural Guidelines]] - [[TRaSH Guide Structural Guidelines]]
See the "Pages" list on the right side of this page for the complete list of wiki pages. See the "Pages" list on the right side of this page for the complete list of wiki pages.

@ -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`<br>
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
Loading…
Cancel
Save