Add asset pass to merge text files in directories.

This massively reduces the file count of published SS14 builds by a few thousand, by combining YAML prototypes and Fluent files in the same folder into one file.
This commit is contained in:
PJB3005
2025-07-25 15:57:18 +02:00
parent 1ebac7c894
commit d1c6c11755
6 changed files with 288 additions and 1 deletions

View File

@@ -0,0 +1,76 @@
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Packaging.AssetProcessing.Passes;
namespace Robust.UnitTesting.Packaging;
[Parallelizable(ParallelScope.All)]
[TestFixture]
[TestOf(typeof(AssetPassMergeTextDirectories))]
internal sealed class AssetPassMergeTextDirectoriesTest
{
[Test]
public async Task Test()
{
var pass = new AssetPassMergeTextDirectories("/Prototypes", "yml", f => $"# BEGIN: {f}", f => $"# END: {f}");
var collectorPass = AssetPassTest.SetupTestPass(pass);
pass.InjectFileFromMemory("/Prototypes/LICENSE.txt", "Do whatever\n"u8);
pass.InjectFileFromMemory("/Prototypes/b.yml", "# file: B\n"u8);
pass.InjectFileFromMemory("/Prototypes/a.yml", "# file: A\n"u8);
pass.InjectFileFromMemory("/Prototypes/z/d.yml", "# file: D\n"u8);
pass.InjectFileFromMemory("/Prototypes/z/c.yml", "# file: C\n"u8);
pass.InjectFinished();
await collectorPass.FinishedTask;
collectorPass.AssertTextFiles(
("/Prototypes/__merged.yml", """
# BEGIN: /Prototypes/a.yml
# file: A
# END: /Prototypes/a.yml
# BEGIN: /Prototypes/b.yml
# file: B
# END: /Prototypes/b.yml
""".Replace("\r\n", "\n")),
("/Prototypes/z/__merged.yml", """
# BEGIN: /Prototypes/z/c.yml
# file: C
# END: /Prototypes/z/c.yml
# BEGIN: /Prototypes/z/d.yml
# file: D
# END: /Prototypes/z/d.yml
""".Replace("\r\n", "\n")));
}
[Test]
public async Task TestNormalizeEol()
{
var pass = new AssetPassMergeTextDirectories("/", "yml");
var collectorPass = AssetPassTest.SetupTestPass(pass);
pass.InjectFileFromMemory("/b.yml", "# file: B\r\n"u8);
pass.InjectFileFromMemory("/a.yml", "# file: A\n"u8);
pass.InjectFinished();
await collectorPass.FinishedTask;
collectorPass.AssertTextFiles(
("/__merged.yml", "# file: A\n# file: B\n"));
}
[Test]
public async Task TestFixBom()
{
var pass = new AssetPassMergeTextDirectories("/", "yml");
var collectorPass = AssetPassTest.SetupTestPass(pass);
pass.InjectFileFromMemory("/b.yml", "\uFEFF# file: B\n"u8);
pass.InjectFileFromMemory("/a.yml", "\uFEFF# file: A\n"u8);
pass.InjectFinished();
await collectorPass.FinishedTask;
collectorPass.AssertTextFiles(
("/__merged.yml", "# file: A\n# file: B\n"));
}
}

View File

@@ -0,0 +1,28 @@
using NUnit.Framework;
using Robust.Packaging.AssetProcessing;
namespace Robust.UnitTesting.Packaging;
/// <summary>
/// Helper class for testing <see cref="AssetPass"/>.
/// </summary>
public static class AssetPassTest
{
/// <summary>
/// Make an asset pass write into a <see cref="AssetPassTestCollector"/> and resolve the graph.
/// </summary>
/// <remarks>
/// The resolved graph logs to the NUnit test context.
/// </remarks>
public static AssetPassTestCollector SetupTestPass(AssetPass testedPass)
{
var logger = new PackageLoggerNUnit(TestContext.Out);
var collectorPass = new AssetPassTestCollector();
collectorPass.AddDependency(testedPass);
AssetGraph.CalculateGraph([testedPass, collectorPass], logger);
return collectorPass;
}
}

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using Robust.Packaging.AssetProcessing;
namespace Robust.UnitTesting.Packaging;
/// <summary>
/// A simple asset pass that stores all files it receives, for introspection by tests.
/// </summary>
public sealed class AssetPassTestCollector : AssetPass
{
public readonly List<AssetFile> Files = [];
protected override AssetFileAcceptResult AcceptFile(AssetFile file)
{
lock (Files)
{
Files.Add(file);
}
return AssetFileAcceptResult.Consumed;
}
/// <summary>
/// Assert that the only files collected are an exact set of test files.
/// </summary>
public void AssertTextFiles(params (string path, string data)[] files)
{
lock (Files)
{
Assert.That(Files, Has.Count.EqualTo(files.Length));
Assert.Multiple(() =>
{
foreach (var file in files)
{
var matchingFile = Files.SingleOrDefault(f => f.Path == file.path);
if (matchingFile == null)
{
Assert.Fail($"Unable to find file {file.path}");
continue;
}
using var fileData = matchingFile.Open();
using var reader = new StreamReader(fileData);
var fileText = reader.ReadToEnd();
Assert.That(fileText, Is.EqualTo(file.data));
}
});
}
}
}

View File

@@ -0,0 +1,17 @@
using System.IO;
using Robust.Packaging;
using Robust.Shared.Log;
namespace Robust.UnitTesting.Packaging;
/// <summary>
/// Package logger for writing to NUnit's test context.
/// </summary>
/// <param name="writer"></param>
public sealed class PackageLoggerNUnit(TextWriter writer) : IPackageLogger
{
public void Log(LogLevel level, string msg)
{
writer.WriteLine($"[{level}] {msg}");
}
}