feat: added some single entity processing methods

This commit is contained in:
Dylan R. E. Moonfire 2022-07-18 17:03:30 -05:00
parent 516aeb254b
commit d1c73f2bce
5 changed files with 292 additions and 0 deletions

View file

@ -0,0 +1,14 @@
namespace Nitride.IO;
public enum IfFoundOutput
{
/// <summary>
/// If the entity is found, then remove it from output.
/// </summary>
RemoveFromOutput,
/// <summary>
/// If the entity is found, then keep it in the output sequence.
/// </summary>
ReturnInOutput,
}

View file

@ -12,6 +12,7 @@
<PackageReference Include="DotNet.Glob" Version="3.1.3" /> <PackageReference Include="DotNet.Glob" Version="3.1.3" />
<PackageReference Include="FluentValidation" Version="11.1.0" /> <PackageReference Include="FluentValidation" Version="11.1.0" />
<PackageReference Include="Gallium" Version="1.4.0" /> <PackageReference Include="Gallium" Version="1.4.0" />
<PackageReference Include="MAB.DotIgnore" Version="3.0.2" />
<PackageReference Include="Serilog" Version="2.11.0" /> <PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Zio" Version="0.15.0" /> <PackageReference Include="Zio" Version="0.15.0" />
</ItemGroup> </ItemGroup>

View file

@ -0,0 +1,90 @@
using System.Collections.Generic;
using Gallium;
using MAB.DotIgnore;
using Zio;
namespace Nitride.IO;
/// <summary>
/// Extension methods for working with paths.
/// </summary>
public static class NitrideIOEnumerableEntityExtensions
{
/// <summary>
/// Retrieves an entity from the sequence of entities.
/// </summary>
/// <param name="input">The sequence of iterations to parse.</param>
/// <param name="path">The path to search for.</param>
/// <param name="foundEntity">The entity pulled out, if found. Otherwise null.</param>
/// <param name="removeFromResults">If true, then remove the entity from the list.</param>
/// <returns>The sequence of entities, optionally without one.</returns>
public static IEnumerable<Entity> GetEntityByPath(
this IEnumerable<Entity> input,
UPath path,
out Entity? foundEntity,
IfFoundOutput removeFromResults = IfFoundOutput.RemoveFromOutput)
{
List<Entity> output = new();
foundEntity = null;
foreach (Entity entity in input)
{
// If we don't have a path, it isn't it.
if (!entity.TryGet(out UPath entityPath))
{
output.Add(entity);
continue;
}
// See if the path matches. If it doesn't, then return it.
if (entityPath != path)
{
output.Add(entity);
continue;
}
// We found the entity, so optionally return it.
foundEntity = entity;
if (removeFromResults == IfFoundOutput.ReturnInOutput)
{
output.Add(entity);
}
}
// Return the resulting output.
return output;
}
/// <summary>
/// Filters out entities that match a .gitignore style list and returns
/// the remaining entities.
/// </summary>
public static IEnumerable<Entity> WhereNotIgnored(
this IEnumerable<Entity> input,
IgnoreList ignoreList)
{
foreach (Entity entity in input)
{
// If we don't have a path, nothing to do.
if (!entity.TryGet(out UPath path))
{
yield return entity;
}
// See if the path matches. We use the "path is directory" set to false
// because Entity represents files, not directories.
string text = path.ToString();
if (!ignoreList.IsIgnored(text, false))
{
yield return entity;
}
}
}
}

View file

@ -0,0 +1,129 @@
using System.Linq;
using Gallium;
using Nitride.IO.Contents;
using Xunit;
using Xunit.Abstractions;
using Zio;
namespace Nitride.IO.Tests;
public class GetEntityByPathTests : NitrideIOTestBase
{
public GetEntityByPathTests(ITestOutputHelper output)
: base(output)
{
}
[Fact]
public void FoundFile()
{
// Set up the test.
using NitrideIOTestContext context = this.CreateContext();
// Set up the file.
IFileSystem fileSystem = context.FileSystem;
fileSystem.CreateFile("/b1.txt");
fileSystem.CreateFile("/c1.md");
// Set up the operation.
ReadFiles readFiles = context.Resolve<ReadFiles>();
// Read and replace the paths.
IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
.Run()
.GetEntityByPath("/c1.md", out Entity? found)
.Select(
x => x.Get<UPath>()
.ToString())
.OrderBy(x => x);
// Verify the results.
Assert.Equal(
new[]
{
"/b1.txt",
},
output);
Assert.NotNull(found);
Assert.Equal("/c1.md", found!.Get<UPath>());
}
[Fact]
public void FoundFileAndKeep()
{
// Set up the test.
using NitrideIOTestContext context = this.CreateContext();
// Set up the file.
IFileSystem fileSystem = context.FileSystem;
fileSystem.CreateFile("/b1.txt");
fileSystem.CreateFile("/c1.md");
// Set up the operation.
ReadFiles readFiles = context.Resolve<ReadFiles>();
// Read and replace the paths.
IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
.Run()
.GetEntityByPath("/c1.md", out Entity? found, IfFoundOutput.ReturnInOutput)
.Select(
x => x.Get<UPath>()
.ToString())
.OrderBy(x => x);
// Verify the results.
Assert.Equal(
new[]
{
"/b1.txt",
"/c1.md",
},
output);
Assert.NotNull(found);
Assert.Equal("/c1.md", found!.Get<UPath>());
}
[Fact]
public void NotFoundFile()
{
// Set up the test.
using NitrideIOTestContext context = this.CreateContext();
// Set up the file.
IFileSystem fileSystem = context.FileSystem;
fileSystem.CreateFile("/b1.txt");
fileSystem.CreateFile("/c1.md");
// Set up the operation.
ReadFiles readFiles = context.Resolve<ReadFiles>();
// Read and replace the paths.
IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
.Run()
.GetEntityByPath("/not-found.md", out Entity? found)
.Select(
x => x.Get<UPath>()
.ToString())
.OrderBy(x => x);
// Verify the results.
Assert.Equal(
new[]
{
"/b1.txt",
"/c1.md",
},
output);
Assert.Null(found);
}
}

View file

@ -0,0 +1,58 @@
using System.Linq;
using MAB.DotIgnore;
using Nitride.IO.Contents;
using Xunit;
using Xunit.Abstractions;
using Zio;
namespace Nitride.IO.Tests;
public class WhereNotIgnoredTests : NitrideIOTestBase
{
public WhereNotIgnoredTests(ITestOutputHelper output)
: base(output)
{
}
[Fact]
public void DoesIgnore()
{
// Set up the test.
using NitrideIOTestContext context = this.CreateContext();
// Set up the file.
IFileSystem fileSystem = context.FileSystem;
fileSystem.CreateFile("/b1.txt");
fileSystem.CreateFile("/c1.md");
fileSystem.CreateDirectory("/d");
fileSystem.CreateFile("/d/b2.txt");
// Set up the ignore file.
var ignore = new IgnoreList(new[] { "*.txt" });
// Set up the operation.
ReadFiles readFiles = context.Resolve<ReadFiles>();
// Read and replace the paths.
IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
.Run()
.WhereNotIgnored(ignore)
.Select(
x => x.Get<UPath>()
.ToString())
.OrderBy(x => x);
// Verify the results.
Assert.Equal(
new[]
{
"/c1.md",
},
output);
}
}