Skip to content

Commit 7e2c652

Browse files
committed
Fix for multi mod master read-in logic after lib update
1 parent 168f4b3 commit 7e2c652

File tree

6 files changed

+47
-77
lines changed

6 files changed

+47
-77
lines changed

Mutagen.Bethesda.Synthesis/Pipeline/SynthesisPipeline.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ private async Task Run(
648648
if (prefs.NoPatch) return;
649649

650650
System.Console.WriteLine($"Writing to output: {args.OutputPath}");
651-
Directory.CreateDirectory(Path.GetDirectoryName(args.OutputPath)!);
651+
fileSystem.Directory.CreateDirectory(Path.GetDirectoryName(args.OutputPath)!);
652652

653653
try
654654
{

Mutagen.Bethesda.Synthesis/States/DI/PatcherStateFactory.cs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,39 @@ public SynthesisState<TModSetter, TModGetter> ToState<TModSetter, TModGetter>(Ru
291291
{
292292
var modPath = new ModPath(exportKey, settings.SourcePath!);
293293

294-
if (_fileSystem.File.Exists(modPath.Path))
294+
// Check for split files first when enabled, since the base name
295+
// file may itself be the first split file
296+
if (settings.SplitIfMaxMastersExceeded)
297+
{
298+
var sourceModKey = ModKey.FromFileName(Path.GetFileName(settings.SourcePath!));
299+
var sourceModPath = new ModPath(sourceModKey, settings.SourcePath!);
300+
301+
if (MultiModFileAnalysis.IsMultiModFile(sourceModPath, fileSystem: _fileSystem))
302+
{
303+
patchMod = ImportAndMergeSplitFiles<TModSetter, TModGetter>(
304+
sourceModPath,
305+
exportKey,
306+
settings,
307+
stringReadParams);
308+
}
309+
else if (_fileSystem.File.Exists(modPath.Path))
310+
{
311+
patchMod = ModFactory<TModSetter>.Importer(
312+
modPath,
313+
settings.GameRelease,
314+
new BinaryReadParameters()
315+
{
316+
FileSystem = _fileSystem,
317+
StringsParam = stringReadParams
318+
});
319+
}
320+
else
321+
{
322+
throw new FileNotFoundException(modPath.Path);
323+
}
324+
}
325+
else if (_fileSystem.File.Exists(modPath.Path))
295326
{
296-
// Normal case - source file exists
297327
patchMod = ModFactory<TModSetter>.Importer(
298328
modPath,
299329
settings.GameRelease,
@@ -305,30 +335,7 @@ public SynthesisState<TModSetter, TModGetter> ToState<TModSetter, TModGetter>(Ru
305335
}
306336
else
307337
{
308-
// Check for split files only if enabled
309-
if (settings.SplitIfMaxMastersExceeded)
310-
{
311-
var sourceModKey = ModKey.FromFileName(Path.GetFileName(settings.SourcePath!));
312-
var sourceModPath = new ModPath(sourceModKey, settings.SourcePath!);
313-
314-
if (MultiModFileAnalysis.IsMultiModFile(sourceModPath, fileSystem: _fileSystem))
315-
{
316-
// Split files exist - read and merge them
317-
patchMod = ImportAndMergeSplitFiles<TModSetter, TModGetter>(
318-
sourceModPath,
319-
exportKey,
320-
settings,
321-
stringReadParams);
322-
}
323-
else
324-
{
325-
throw new FileNotFoundException(modPath.Path);
326-
}
327-
}
328-
else
329-
{
330-
throw new FileNotFoundException(modPath.Path);
331-
}
338+
throw new FileNotFoundException(modPath.Path);
332339
}
333340
}
334341
if (settings.PersistencePath is not null && settings.PatcherName is not null)

Synthesis.Bethesda.IntegrationTests/Pipeline/SingleGitPatcherAutoSplitTest.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,10 @@ public async Task SingleGitPatcher_CreatesTooManyMasters_CreatesSplitFiles()
5858
await AssertNoErrors();
5959

6060
// Verify split files were created
61-
var baseOutputPath = Path.Combine(DataFolder, $"{groupName}.esp");
62-
var splitFile1Path = Path.Combine(DataFolder, $"{groupName}_1.esp");
61+
// First split has no suffix (base name), second split is _2
62+
var splitFile1Path = Path.Combine(DataFolder, $"{groupName}.esp");
6363
var splitFile2Path = Path.Combine(DataFolder, $"{groupName}_2.esp");
6464

65-
File.Exists(baseOutputPath).ShouldBeFalse("Base output file should not exist");
6665
File.Exists(splitFile1Path).ShouldBeTrue("First split file should exist");
6766
File.Exists(splitFile2Path).ShouldBeTrue("Second split file should exist");
6867

Synthesis.Bethesda.IntegrationTests/Pipeline/TwoGitPatchersAutoSplitTest.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,14 @@ public async Task TwoGitPatchers_FirstCreatesSplitFiles_SecondModifiesContent()
6565
await AssertNoErrors();
6666

6767
// Verify split files were created
68-
var baseOutputPath = Path.Combine(DataFolder, $"{groupName}.esp");
69-
var splitFile1Path = Path.Combine(DataFolder, $"{groupName}_1.esp");
68+
// First split has no suffix (base name), second split is _2
69+
var splitFile1Path = Path.Combine(DataFolder, $"{groupName}.esp");
7070
var splitFile2Path = Path.Combine(DataFolder, $"{groupName}_2.esp");
7171

72-
File.Exists(baseOutputPath).ShouldBeFalse("Base output file should not exist");
7372
File.Exists(splitFile1Path).ShouldBeTrue("First split file should exist");
7473
File.Exists(splitFile2Path).ShouldBeTrue("Second split file should exist");
7574

76-
// Verify the base file and split files can be loaded
75+
// Verify the split files can be loaded
7776
using var split1Mod = SkyrimMod.CreateFromBinaryOverlay(splitFile1Path, SkyrimRelease.SkyrimSE);
7877
using var split2Mod = SkyrimMod.CreateFromBinaryOverlay(splitFile2Path, SkyrimRelease.SkyrimSE);
7978

Synthesis.Bethesda.UnitTests/Execution/Running/Runner/FinalizePatcherRunTests.cs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,41 +33,6 @@ public async Task OutputFileExistsReturnsOutputPath(
3333
.ShouldBe(existingOutput.Path);
3434
}
3535

36-
[Theory]
37-
[SynthCustomInlineData(FileSystem: TargetFileSystem.Substitute)]
38-
public void SplitFilesExistReturnsBasePath(
39-
IPatcherPrepAndRun patcher,
40-
IRunReporter reporter,
41-
[Frozen] IFileSystem fileSystem,
42-
FinalizePatcherRun sut)
43-
{
44-
// Set up split files without the main output file
45-
var outputDir = @"C:\Output";
46-
var outputModKey = ModKey.FromFileName("Patch.esp");
47-
var outputPath = Path.Combine(outputDir, outputModKey.FileName);
48-
49-
// Main file doesn't exist
50-
fileSystem.File.Exists(outputPath).Returns(false);
51-
52-
// Split files exist
53-
var splitFile1 = Path.Combine(outputDir, "Patch_1.esp");
54-
var splitFile2 = Path.Combine(outputDir, "Patch_2.esp");
55-
56-
fileSystem.File.Exists(splitFile1).Returns(true);
57-
fileSystem.File.Exists(splitFile2).Returns(true);
58-
59-
// Set up directory enumeration for MultiModFileAnalysis
60-
fileSystem.Directory.Exists(outputDir).Returns(true);
61-
fileSystem.Directory.EnumerateFiles(outputDir, "Patch_*.esp", SearchOption.TopDirectoryOnly)
62-
.Returns(new[] { splitFile1, splitFile2 });
63-
64-
var result = sut.Finalize(patcher, outputPath);
65-
66-
// Should return the base path even though the main file doesn't exist
67-
result.ShouldNotBeNull();
68-
result.Value.Path.ShouldBe(outputPath);
69-
}
70-
7136
[Theory]
7237
[SynthCustomInlineData(FileSystem: TargetFileSystem.Substitute)]
7338
public void NoOutputAndNoSplitFilesReturnsNull(

Synthesis.Bethesda.UnitTests/Pipeline/SynthesisPipelineTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -689,10 +689,11 @@ await SynthesisPipeline.Instance
689689
.Run(runArgs, fileSystem);
690690

691691
// Verify multiple output files were created
692+
// First split has no suffix (base name), second split is _2
692693
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(outputModKey.FileName);
693694
var extension = Path.GetExtension(outputModKey.FileName);
694695

695-
var splitFile1 = Path.Combine(outputPath, $"{fileNameWithoutExtension}_1{extension}");
696+
var splitFile1 = Path.Combine(outputPath, $"{fileNameWithoutExtension}{extension}");
696697
var splitFile2 = Path.Combine(outputPath, $"{fileNameWithoutExtension}_2{extension}");
697698

698699
fileSystem.File.Exists(splitFile1).ShouldBeTrue($"Expected split file 1 to exist: {splitFile1}");
@@ -783,7 +784,8 @@ public async Task ImportsSplitSourceFiles(
783784
}
784785
expectedFormLists.Add((formList1.EditorID, items1));
785786

786-
var splitFile1Path = Path.Combine(dataFolder, $"{sourceModKey.Name}_1{Path.GetExtension(sourceModKey.FileName)}");
787+
// First split file uses the base name (no suffix)
788+
var splitFile1Path = Path.Combine(dataFolder, sourceModKey.FileName);
787789
splitMod1.BeginWrite
788790
.ToPath(splitFile1Path)
789791
.WithNoLoadOrder()
@@ -805,6 +807,7 @@ public async Task ImportsSplitSourceFiles(
805807
}
806808
expectedFormLists.Add((formList2.EditorID, items2));
807809

810+
// Second split file uses _2 suffix
808811
var splitFile2Path = Path.Combine(dataFolder, $"{sourceModKey.Name}_2{Path.GetExtension(sourceModKey.FileName)}");
809812
splitMod2.BeginWrite
810813
.ToPath(splitFile2Path)
@@ -816,7 +819,7 @@ public async Task ImportsSplitSourceFiles(
816819
// Create plugins.txt with all masters AND the split files
817820
var pluginPath = Path.Combine(dataFolder, "Plugins.txt");
818821
var pluginLines = masterModKeys.Select(k => $"*{k.FileName}").ToList();
819-
pluginLines.Add($"*{sourceModKey.Name}_1{Path.GetExtension(sourceModKey.FileName)}");
822+
pluginLines.Add($"*{sourceModKey.FileName}");
820823
pluginLines.Add($"*{sourceModKey.Name}_2{Path.GetExtension(sourceModKey.FileName)}");
821824
fileSystem.File.WriteAllLines(pluginPath, pluginLines);
822825

@@ -828,7 +831,7 @@ public async Task ImportsSplitSourceFiles(
828831
DataFolderPath = dataFolder,
829832
LoadOrderFilePath = pluginPath,
830833
GameRelease = GameRelease.SkyrimSE,
831-
SourcePath = Path.Combine(dataFolder, sourceModKey.FileName), // Base name, doesn't exist
834+
SourcePath = Path.Combine(dataFolder, sourceModKey.FileName), // Base name (first split file)
832835
OutputPath = Path.Combine(outputPath, outputModKey.FileName),
833836
LoadOrderIncludesCreationClub = true,
834837
SplitIfMaxMastersExceeded = true // Enable split file detection
@@ -878,11 +881,8 @@ await SynthesisPipeline.Instance
878881
loadOrderKeys.ShouldContain(outputModKey,
879882
$"Load order should contain output ModKey {outputModKey}");
880883

881-
// Should NOT contain the split file keys
882-
var splitKey1 = new ModKey($"{sourceModKey.Name}_1", sourceModKey.Type);
884+
// Should NOT contain the split sibling file key
883885
var splitKey2 = new ModKey($"{sourceModKey.Name}_2", sourceModKey.Type);
884-
loadOrderKeys.ShouldNotContain(splitKey1,
885-
$"Load order should not contain split file {splitKey1}");
886886
loadOrderKeys.ShouldNotContain(splitKey2,
887887
$"Load order should not contain split file {splitKey2}");
888888
}

0 commit comments

Comments
 (0)