refactor: Upgrade System.IO.Abstractions (with code changes)

pull/151/head
Robert Dailey 2 years ago
commit 37ff650152

@ -58,8 +58,8 @@ public class FileSystemExtensionsTest
var fs = NewMockFileSystem(files, dirs, @"C:\root\path");
fs.MergeDirectory(
fs.DirectoryInfo.FromDirectoryName("path1"),
fs.DirectoryInfo.FromDirectoryName("path2"));
fs.DirectoryInfo.New("path1"),
fs.DirectoryInfo.New("path2"));
fs.AllDirectories.Select(MockUnixSupport.Path).Should()
.NotContain(x => x.Contains("path1") || x.Contains("empty"));
@ -80,8 +80,8 @@ public class FileSystemExtensionsTest
var fs = NewMockFileSystem(files, @"C:\root\path");
var act = () => fs.MergeDirectory(
fs.DirectoryInfo.FromDirectoryName("path1"),
fs.DirectoryInfo.FromDirectoryName("path2"));
fs.DirectoryInfo.New("path1"),
fs.DirectoryInfo.New("path2"));
act.Should().Throw<IOException>();
}
@ -102,8 +102,8 @@ public class FileSystemExtensionsTest
var fs = NewMockFileSystem(files, dirs, @"C:\root\path");
var act = () => fs.MergeDirectory(
fs.DirectoryInfo.FromDirectoryName("path1"),
fs.DirectoryInfo.FromDirectoryName("path2"));
fs.DirectoryInfo.New("path1"),
fs.DirectoryInfo.New("path2"));
act.Should().Throw<IOException>();
}

@ -2,6 +2,7 @@ using System.IO.Abstractions;
using System.IO.Abstractions.Extensions;
using System.IO.Abstractions.TestingHelpers;
using FluentAssertions;
using NSubstitute;
using NUnit.Framework;
using Serilog;
using Serilog.Events;
@ -91,4 +92,14 @@ public class JsonUtilsTest
.Which.RenderMessage()
.Should().Match("*does_not_exist*");
}
[Test]
public void Null_paths_are_ignored()
{
var result = JsonUtils.GetJsonFilesInDirectories(
new IDirectoryInfo?[] {null, null},
Substitute.For<ILogger>());
result.Should().BeEmpty();
}
}

@ -6,8 +6,9 @@
<PackageReference Include="Flurl.Http" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Serilog" />
<PackageReference Include="System.IO.Abstractions" />
<PackageReference Include="System.Reactive" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" />
<PackageReference Include="TestableIO.System.IO.Abstractions" />
<PackageReference Include="YamlDotNet" />
</ItemGroup>
</Project>

@ -6,6 +6,21 @@ namespace Common.Extensions;
public static class FileSystemExtensions
{
public static void CreateParentDirectory(this IFileInfo f)
{
var parent = f.Directory;
parent?.Create();
}
public static void CreateParentDirectory(this IFileSystem fs, string? path)
{
var dirName = fs.Path.GetDirectoryName(path);
if (dirName is not null)
{
fs.Directory.CreateDirectory(dirName);
}
}
public static void MergeDirectory(this IFileSystem fs, IDirectoryInfo targetDir, IDirectoryInfo destDir,
IConsole? console = null)
{
@ -22,7 +37,7 @@ public static class FileSystemExtensions
if ((dir.Attributes & FileAttributes.ReparsePoint) != 0)
{
var newPath = RelocatePath(dir.FullName, targetDir.FullName, destDir.FullName);
fs.Directory.CreateDirectory(fs.Path.GetDirectoryName(newPath));
fs.CreateParentDirectory(newPath);
console?.Output.WriteLine($" - Symlink: {dir.FullName} :: TO :: {newPath}");
dir.MoveTo(newPath);
continue;
@ -32,7 +47,7 @@ public static class FileSystemExtensions
foreach (var file in dir.EnumerateFiles())
{
var newPath = RelocatePath(file.FullName, targetDir.FullName, destDir.FullName);
fs.Directory.CreateDirectory(fs.Path.GetDirectoryName(newPath));
fs.CreateParentDirectory(newPath);
console?.Output.WriteLine($" - Moving: {file.FullName} :: TO :: {newPath}");
file.MoveTo(newPath);
}

@ -25,7 +25,7 @@ public class FileUtilities : IFileUtilities
foreach (var fileName in Directory.EnumerateFiles(directory))
{
var fileInfo = _fileSystem.FileInfo.FromFileName(fileName);
var fileInfo = _fileSystem.FileInfo.New(fileName);
fileInfo.Attributes = FileAttributes.Normal;
fileInfo.Delete();
}

@ -1,13 +1,14 @@
using System.IO.Abstractions;
using Common.Extensions;
using Serilog;
namespace Common;
public static class JsonUtils
{
public static IEnumerable<IFileInfo> GetJsonFilesInDirectories(IEnumerable<IDirectoryInfo> dirs, ILogger log)
public static IEnumerable<IFileInfo> GetJsonFilesInDirectories(IEnumerable<IDirectoryInfo?> dirs, ILogger log)
{
var dirsThatExist = dirs.ToLookup(x => x.Exists);
var dirsThatExist = dirs.NotNull().ToLookup(x => x.Exists);
foreach (var dir in dirsThatExist[false])
{

@ -53,8 +53,8 @@
<PackageReference Include="NUnit3TestAdapter" PrivateAssets="All" />
<PackageReference Include="Serilog.Sinks.NUnit" PrivateAssets="All" />
<PackageReference Include="Serilog.Sinks.TestCorrelator" PrivateAssets="All" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" PrivateAssets="All" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Extensions" PrivateAssets="All" />
<PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition="$(ProjectName.EndsWith('.Tests')) Or $(ProjectName.EndsWith('.TestLibrary'))">

@ -27,9 +27,10 @@
<PackageVersion Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="System.Data.HashFunction.FNV" Version="2.0.0" />
<PackageVersion Include="System.IO.Abstractions" Version="17.2.3" />
<PackageVersion Include="System.Reactive" Version="5.0.0" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.Extensions" Version="1.0.32" />
<PackageVersion Include="TestableIO.System.IO.Abstractions" Version="18.0.1" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.Extensions" Version="1.0.34" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.Wrappers" Version="18.0.1" />
<PackageVersion Include="YamlDotNet" Version="12.0.2" />
</ItemGroup>
<!-- Unit Test Packages -->
@ -50,7 +51,7 @@
<PackageVersion Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageVersion Include="Serilog.Sinks.NUnit" Version="1.0.3" />
<PackageVersion Include="Serilog.Sinks.TestCorrelator" Version="3.2.0" />
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="17.2.3" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="18.0.1" />
</ItemGroup>
<!-- Following found during vulerabilities Code Scan -->
<ItemGroup>

@ -3,6 +3,7 @@ using Autofac;
using CliFx.Attributes;
using CliFx.Exceptions;
using Common;
using Common.Extensions;
using JetBrains.Annotations;
using Serilog;
using TrashLib.Startup;
@ -28,7 +29,7 @@ public class CreateConfigCommand : BaseCommand
var reader = new ResourceDataReader(typeof(Program));
var ymlData = reader.ReadData("config-template.yml");
var configFile = AppDataDirectory is not null
? fs.FileInfo.FromFileName(AppDataDirectory)
? fs.FileInfo.New(AppDataDirectory)
: paths.ConfigPath;
if (configFile.Exists)
@ -37,7 +38,7 @@ public class CreateConfigCommand : BaseCommand
"delete/move the existing file and run this command again.");
}
fs.Directory.CreateDirectory(configFile.DirectoryName);
configFile.CreateParentDirectory();
await using var stream = configFile.CreateText();
await stream.WriteAsync(ymlData);
log.Information("Created configuration at: {Path}", configFile);

@ -12,7 +12,8 @@
<PackageReference Include="Serilog" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="System.IO.Abstractions" />
<PackageReference Include="TestableIO.System.IO.Abstractions" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" />
<PackageReference Include="YamlDotNet" />
</ItemGroup>

@ -51,7 +51,7 @@ public class ServiceCacheTest
const string testJsonPath = "cacheFile.json";
fs.AddFile(testJsonPath, new MockFileData(testJson));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName(testJsonPath));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New(testJsonPath));
var obj = sut.Load<ObjectWithAttribute>();
@ -85,7 +85,7 @@ public class ServiceCacheTest
[Frozen] ICacheStoragePath storage,
ServiceCache sut)
{
storage.CalculatePath(default!).ReturnsForAnyArgs(_ => fs.FileInfo.FromFileName($"{ValidObjectName}.json"));
storage.CalculatePath(default!).ReturnsForAnyArgs(_ => fs.FileInfo.New($"{ValidObjectName}.json"));
sut.Save(new ObjectWithAttribute {TestValue = "Foo"});
@ -103,7 +103,7 @@ public class ServiceCacheTest
ServiceCache sut)
{
const string testJsonPath = "cacheFile.json";
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName(testJsonPath));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New(testJsonPath));
sut.Save(new ObjectWithAttribute {TestValue = "Foo"});
@ -140,10 +140,10 @@ public class ServiceCacheTest
[Frozen] ICacheStoragePath storage,
ServiceCache sut)
{
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName("Foo.json"));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New("Foo.json"));
sut.Save(new ObjectWithAttribute {TestValue = "Foo"});
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName("Bar.json"));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New("Bar.json"));
sut.Save(new ObjectWithAttribute {TestValue = "Bar"});
var expectedFiles = new[] {"*Foo.json", "*Bar.json"};
@ -159,7 +159,7 @@ public class ServiceCacheTest
[Frozen] ICacheStoragePath storage,
ServiceCache sut)
{
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName("cacheFile.json"));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New("cacheFile.json"));
fs.AddFile("cacheFile.json", new MockFileData(""));
Action act = () => sut.Load<ObjectWithAttribute>();
@ -187,7 +187,7 @@ public class ServiceCacheTest
";
fs.AddFile("cacheFile.json", new MockFileData(cacheJson));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.FromFileName("cacheFile.json"));
storage.CalculatePath(default!).ReturnsForAnyArgs(fs.FileInfo.New("cacheFile.json"));
var result = sut.Load<CustomFormatCache>();

@ -1,6 +1,7 @@
using System.IO.Abstractions;
using System.Reflection;
using System.Text.RegularExpressions;
using Common.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Serilog;
@ -55,7 +56,7 @@ public class ServiceCache : IServiceCache
public void Save<T>(T obj) where T : class
{
var path = PathFromAttribute<T>();
path.Directory.Create();
path.CreateParentDirectory();
var serializer = JsonSerializer.Create(_jsonSettings);

@ -1,3 +1,4 @@
using Common.Extensions;
using TrashLib.Startup;
namespace TrashLib.Config.Settings;
@ -36,7 +37,7 @@ public class SettingsProvider : ISettingsProvider
"# For the settings file reference guide, visit the link to the wiki below:\n" +
"# https://github.com/recyclarr/recyclarr/wiki/Settings-Reference\n";
_paths.SettingsPath.Directory.Create();
_paths.SettingsPath.CreateParentDirectory();
using var stream = _paths.SettingsPath.CreateText();
stream.Write(fileData);
}

@ -18,7 +18,7 @@ public class DefaultAppDataSetup
public IAppPaths CreateAppPaths(string? appDataDirectoryOverride = null, bool forceCreate = true)
{
var appDir = GetAppDataDirectory(appDataDirectoryOverride, forceCreate);
return new AppPaths(_fs.DirectoryInfo.FromDirectoryName(appDir));
return new AppPaths(_fs.DirectoryInfo.New(appDir));
}
private string GetAppDataDirectory(string? appDataDirectoryOverride, bool forceCreate)

@ -13,9 +13,10 @@
<PackageReference Include="Newtonsoft.Json.Schema" />
<PackageReference Include="Serilog" />
<PackageReference Include="System.Data.HashFunction.FNV" />
<PackageReference Include="System.IO.Abstractions" />
<PackageReference Include="System.Reactive" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Extensions" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" />
<PackageReference Include="TestableIO.System.IO.Abstractions" />
</ItemGroup>
<ItemGroup>

Loading…
Cancel
Save