Skip to content

Commit

Permalink
Implement :LAST pass
Browse files Browse the repository at this point in the history
Addresses #96

Not to be confused with the popular password manager
  • Loading branch information
blowfishpro committed Apr 6, 2018
1 parent 5b1d22e commit 657c674
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 2 deletions.
7 changes: 7 additions & 0 deletions ModuleManager/PatchApplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public void ApplyPatches()
ApplyPatches($":AFTER[{upperModName}]", pass.afterPatches);
}

// Need another loop here since these should all run after BEFORE/FOR/AFTER for every mod
foreach (PatchList.ModPass pass in patchList.modPasses)
{
string upperModName = pass.name.ToUpper();
ApplyPatches($":LAST[{upperModName}]", pass.lastPatches);
}

// :Final node
ApplyPatches(":FINAL", patchList.finalPatches);
}
Expand Down
22 changes: 22 additions & 0 deletions ModuleManager/PatchExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class PatchExtractor
private static readonly Regex beforeRegex = new Regex(@":BEFORE(?:\[([^\[\]]+)\])?", RegexOptions.IgnoreCase);
private static readonly Regex forRegex = new Regex(@":FOR(?:\[([^\[\]]+)\])?", RegexOptions.IgnoreCase);
private static readonly Regex afterRegex = new Regex(@":AFTER(?:\[([^\[\]]+)\])?", RegexOptions.IgnoreCase);
private static readonly Regex lastRegex = new Regex(@":LAST(?:\[([^\[\]]+)\])?", RegexOptions.IgnoreCase);

public static PatchList SortAndExtractPatches(UrlDir databaseRoot, IEnumerable<string> modList, IPatchProgress progress)
{
Expand All @@ -38,6 +39,7 @@ public static PatchList SortAndExtractPatches(UrlDir databaseRoot, IEnumerable<s
Match beforeMatch = beforeRegex.Match(url.type);
Match forMatch = forRegex.Match(url.type);
Match afterMatch = afterRegex.Match(url.type);
Match lastMatch = lastRegex.Match(url.type);

int matchCount = 0;

Expand All @@ -46,12 +48,14 @@ public static PatchList SortAndExtractPatches(UrlDir databaseRoot, IEnumerable<s
if (beforeMatch.Success) matchCount++;
if (forMatch.Success) matchCount++;
if (afterMatch.Success) matchCount++;
if (lastMatch.Success) matchCount++;

if (firstMatch.NextMatch().Success) matchCount++;
if (finalMatch.NextMatch().Success) matchCount++;
if (beforeMatch.NextMatch().Success) matchCount++;
if (forMatch.NextMatch().Success) matchCount++;
if (afterMatch.NextMatch().Success) matchCount++;
if (lastMatch.NextMatch().Success) matchCount++;

bool error = false;

Expand Down Expand Up @@ -106,6 +110,11 @@ public static PatchList SortAndExtractPatches(UrlDir databaseRoot, IEnumerable<s
progress.Error(url, "Error - malformed :AFTER patch specifier detected: " + url.SafeUrl());
error = true;
}
if (lastMatch.Success && !lastMatch.Groups[1].Success)
{
progress.Error(url, "Error - malformed :LAST patch specifier detected: " + url.SafeUrl());
error = true;
}
if (error)
{
url.parent.configs.Remove(url);
Expand Down Expand Up @@ -169,6 +178,19 @@ public static PatchList SortAndExtractPatches(UrlDir databaseRoot, IEnumerable<s
progress.NeedsUnsatisfiedAfter(url);
}
}
else if (lastMatch.Success)
{
if (CheckMod(lastMatch, list.modPasses, out string theMod))
{
theMatch = lastMatch;
thePass = list.modPasses[theMod].lastPatches;
}
else
{
modNotFound = true;
progress.NeedsUnsatisfiedLast(url);
}
}
else
{
thePass = list.legacyPatches;
Expand Down
1 change: 1 addition & 0 deletions ModuleManager/PatchList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class ModPass
public readonly List<UrlDir.UrlConfig> beforePatches = new List<UrlDir.UrlConfig>(0);
public readonly List<UrlDir.UrlConfig> forPatches = new List<UrlDir.UrlConfig>(0);
public readonly List<UrlDir.UrlConfig> afterPatches = new List<UrlDir.UrlConfig>(0);
public readonly List<UrlDir.UrlConfig> lastPatches = new List<UrlDir.UrlConfig>(0);

public readonly string name;

Expand Down
1 change: 1 addition & 0 deletions ModuleManager/Progress/IPatchProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public interface IPatchProgress
void NeedsUnsatisfiedBefore(UrlDir.UrlConfig url);
void NeedsUnsatisfiedFor(UrlDir.UrlConfig url);
void NeedsUnsatisfiedAfter(UrlDir.UrlConfig url);
void NeedsUnsatisfiedLast(UrlDir.UrlConfig url);
void ApplyingCopy(UrlDir.UrlConfig original, UrlDir.UrlConfig patch);
void ApplyingDelete(UrlDir.UrlConfig original, UrlDir.UrlConfig patch);
void ApplyingUpdate(UrlDir.UrlConfig original, UrlDir.UrlConfig patch);
Expand Down
6 changes: 6 additions & 0 deletions ModuleManager/Progress/PatchProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ public void NeedsUnsatisfiedAfter(UrlDir.UrlConfig url)
Counter.needsUnsatisfied.Increment();
}

public void NeedsUnsatisfiedLast(UrlDir.UrlConfig url)
{
logger.Info($"Deleting root node in file {url.parent.url} node: {url.type} as it can't satisfy its LAST");
Counter.needsUnsatisfied.Increment();
}

public void Error(UrlDir.UrlConfig url, string message)
{
Counter.errors.Increment();
Expand Down
16 changes: 15 additions & 1 deletion ModuleManagerTests/PatchApplierTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,14 @@ public void TestApplyPatches__Order()
{
{ "jj", "010" },
}),
new UrlDir.UrlConfig(file, new TestConfigNode("@PART[000|0*2]")
{
{ "kk", "011" },
}),
new UrlDir.UrlConfig(file, new TestConfigNode("@PART[000|0*2]")
{
{ "ll", "012" },
}),
};

patchList.firstPatches.Add(patches[0]);
Expand All @@ -602,7 +610,9 @@ public void TestApplyPatches__Order()
patchList.modPasses["mod2"].beforePatches.Add(patches[5]);
patchList.modPasses["mod2"].forPatches.Add(patches[6]);
patchList.modPasses["mod2"].afterPatches.Add(patches[7]);
patchList.finalPatches.Add(patches[8]);
patchList.modPasses["mod1"].lastPatches.Add(patches[8]);
patchList.modPasses["mod2"].lastPatches.Add(patches[9]);
patchList.finalPatches.Add(patches[10]);

patchApplier.ApplyPatches();

Expand All @@ -618,6 +628,8 @@ public void TestApplyPatches__Order()
progress.Received().ApplyingUpdate(config1, patches[6]);
progress.Received().ApplyingUpdate(config1, patches[7]);
progress.Received().ApplyingUpdate(config1, patches[8]);
progress.Received().ApplyingUpdate(config1, patches[9]);
progress.Received().ApplyingUpdate(config1, patches[10]);

UrlDir.UrlConfig[] allConfigs = databaseRoot.AllConfigs.ToArray();
Assert.Equal(1, allConfigs.Length);
Expand All @@ -635,6 +647,8 @@ public void TestApplyPatches__Order()
{ "hh", "008" },
{ "ii", "009" },
{ "jj", "010" },
{ "kk", "011" },
{ "ll", "012" },
}, allConfigs[0].config);
}

Expand Down
45 changes: 44 additions & 1 deletion ModuleManagerTests/PatchExtractorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ public void TestSortAndExtractPatches()
CreateConfig("@NADE:AFTER[MOD1]"),
};

UrlDir.UrlConfig[] lastMod1Configs =
{
CreateConfig("@NODE:LAST[mod1]"),
CreateConfig("@NODE[foo]:HAS[#bar]:LAST[mod1]"),
CreateConfig("@NADE:last[mod1]"),
CreateConfig("@NADE:LAST[MOD1]"),
};

UrlDir.UrlConfig[] beforeMod2Configs =
{
CreateConfig("@NODE:BEFORE[mod2]"),
Expand All @@ -102,6 +110,14 @@ public void TestSortAndExtractPatches()
CreateConfig("@NADE:AFTER[MOD2]"),
};

UrlDir.UrlConfig[] lastMod2Configs =
{
CreateConfig("@NODE:LAST[mod2]"),
CreateConfig("@NODE[foo]:HAS[#bar]:LAST[mod2]"),
CreateConfig("@NADE:last[mod2]"),
CreateConfig("@NADE:LAST[MOD2]"),
};

UrlDir.UrlConfig[] beforeMod3Configs =
{
CreateConfig("@NODE:BEFORE[mod3]"),
Expand All @@ -126,6 +142,14 @@ public void TestSortAndExtractPatches()
CreateConfig("@NADE:AFTER[MOD3]"),
};

UrlDir.UrlConfig[] lastMod3Configs =
{
CreateConfig("@NODE:LAST[mod3]"),
CreateConfig("@NODE[foo]:HAS[#bar]:LAST[mod3]"),
CreateConfig("@NADE:last[mod3]"),
CreateConfig("@NADE:LAST[MOD3]"),
};

string[] modList = { "mod1", "mod2" };
PatchList list = PatchExtractor.SortAndExtractPatches(root, modList, progress);

Expand Down Expand Up @@ -178,6 +202,13 @@ public void TestSortAndExtractPatches()
AssertUrlCorrect("@NADE", afterMod1Configs[2], currentPatches[2]);
AssertUrlCorrect("@NADE", afterMod1Configs[3], currentPatches[3]);

currentPatches = list.modPasses["mod1"].lastPatches;
Assert.Equal(lastMod1Configs.Length, currentPatches.Count);
AssertUrlCorrect("@NODE", lastMod1Configs[0], currentPatches[0]);
AssertUrlCorrect("@NODE[foo]:HAS[#bar]", lastMod1Configs[1], currentPatches[1]);
AssertUrlCorrect("@NADE", lastMod1Configs[2], currentPatches[2]);
AssertUrlCorrect("@NADE", lastMod1Configs[3], currentPatches[3]);

currentPatches = list.modPasses["mod2"].beforePatches;
Assert.Equal(beforeMod2Configs.Length, currentPatches.Count);
AssertUrlCorrect("@NODE", beforeMod2Configs[0], currentPatches[0]);
Expand All @@ -199,7 +230,14 @@ public void TestSortAndExtractPatches()
AssertUrlCorrect("@NADE", afterMod2Configs[2], currentPatches[2]);
AssertUrlCorrect("@NADE", afterMod2Configs[3], currentPatches[3]);

progress.Received(34).PatchAdded();
currentPatches = list.modPasses["mod2"].lastPatches;
Assert.Equal(lastMod2Configs.Length, currentPatches.Count);
AssertUrlCorrect("@NODE", lastMod2Configs[0], currentPatches[0]);
AssertUrlCorrect("@NODE[foo]:HAS[#bar]", lastMod2Configs[1], currentPatches[1]);
AssertUrlCorrect("@NADE", lastMod2Configs[2], currentPatches[2]);
AssertUrlCorrect("@NADE", lastMod2Configs[3], currentPatches[3]);

progress.Received(42).PatchAdded();

progress.Received().NeedsUnsatisfiedBefore(beforeMod3Configs[0]);
progress.Received().NeedsUnsatisfiedBefore(beforeMod3Configs[1]);
Expand All @@ -215,6 +253,11 @@ public void TestSortAndExtractPatches()
progress.Received().NeedsUnsatisfiedAfter(afterMod3Configs[1]);
progress.Received().NeedsUnsatisfiedAfter(afterMod3Configs[2]);
progress.Received().NeedsUnsatisfiedAfter(afterMod3Configs[3]);

progress.Received().NeedsUnsatisfiedLast(lastMod3Configs[0]);
progress.Received().NeedsUnsatisfiedLast(lastMod3Configs[1]);
progress.Received().NeedsUnsatisfiedLast(lastMod3Configs[2]);
progress.Received().NeedsUnsatisfiedLast(lastMod3Configs[3]);
}

[Fact]
Expand Down
4 changes: 4 additions & 0 deletions ModuleManagerTests/PatchListTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public void TestModPasses__Accessor()
Assert.Equal(0, pass1.forPatches.Capacity);
Assert.NotNull(pass1.afterPatches);
Assert.Equal(0, pass1.afterPatches.Capacity);
Assert.NotNull(pass1.lastPatches);
Assert.Equal(0, pass1.lastPatches.Capacity);

PatchList.ModPass pass2 = list.modPasses["mod2"];
Assert.NotNull(pass2);
Expand All @@ -66,6 +68,8 @@ public void TestModPasses__Accessor()
Assert.Equal(0, pass2.forPatches.Capacity);
Assert.NotNull(pass2.afterPatches);
Assert.Equal(0, pass2.afterPatches.Capacity);
Assert.NotNull(pass2.lastPatches);
Assert.Equal(0, pass2.lastPatches.Capacity);

Assert.Throws<KeyNotFoundException>(delegate
{
Expand Down
17 changes: 17 additions & 0 deletions ModuleManagerTests/Progress/PatchProgressTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,23 @@ public void TestNeedsUnsatisfiedAfter()
logger.Received().Log(LogType.Log, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its AFTER");
}

[Fact]
public void TestNeedsUnsatisfiedLast()
{
UrlDir.UrlConfig config1 = UrlBuilder.CreateConfig("abc/def", new ConfigNode("SOME_NODE"));
UrlDir.UrlConfig config2 = UrlBuilder.CreateConfig("ghi/jkl", new ConfigNode("SOME_OTHER_NODE"));

Assert.Equal(0, progress.Counter.needsUnsatisfied);

progress.NeedsUnsatisfiedLast(config1);
Assert.Equal(1, progress.Counter.needsUnsatisfied);
logger.Received().Log(LogType.Log, "Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its LAST");

progress.NeedsUnsatisfiedLast(config2);
Assert.Equal(2, progress.Counter.needsUnsatisfied);
logger.Received().Log(LogType.Log, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its LAST");
}

[Fact]
public void TestError()
{
Expand Down

0 comments on commit 657c674

Please sign in to comment.