public void ShouldParseDiffWithNewFileModeLine() { var diff = @" diff --git a/test b/test new file mode 100644 index 0000000..db81be4 --- /dev/null +++ b/test @@ -0,0 +1,2 @@ +line1 +line2 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual(true, file.Type == FileChangeType.Add); Assert.AreEqual("/dev/null", file.From); Assert.AreEqual("test", file.To); Assert.AreEqual("@@ -0,0 +1,2 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual(2, file.Chunks.ElementAt(0).Changes.Count()); Assert.AreEqual("line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.AreEqual("line2", file.Chunks.ElementAt(0).Changes.ElementAt(1).Content); }
public void ShouldParseDiffWithDeletedFileModeLine() { var diff = @" diff --git a/test b/test deleted file mode 100644 index db81be4..0000000 --- b/test +++ /dev/null @@ -1,2 +0,0 @@ -line1 -line2 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.Single(files); var file = files[0]; Assert.True(file.Type == FileChangeType.Delete); Assert.Equal("test", file.From); Assert.Equal("/dev/null", file.To); Assert.Equal("@@ -1,2 +0,0 @@", file.Chunks.ElementAt(0).Content); Assert.Equal(2, file.Chunks.ElementAt(0).Changes.Count()); Assert.Equal("line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.Equal("line2", file.Chunks.ElementAt(0).Changes.ElementAt(1).Content); }
public void ShouldParseSimpleGitLikeDiff() { var diff = @" diff --git a/file b/file index 123..456 789 --- a/file +++ b/file @@ -1,2 +1,2 @@ - line1 + line2"; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("file", file.From); Assert.AreEqual("file", file.To); Assert.AreEqual(1, file.Chunks.Count()); var chunk = file.Chunks.First(); Assert.AreEqual("@@ -1,2 +1,2 @@", chunk.Content); var changes = chunk.Changes.ToArray(); Assert.AreEqual(2, changes.Count()); Assert.AreEqual(" line1", changes[0].Content); Assert.AreEqual(" line2", changes[1].Content); }
public void ShouldParseDiffWIthDeletedFileModeLine() { var diff = @" diff --git a/test b/test deleted file mode 100644 index db81be4..0000000 --- b/test +++ /dev/null @@ -1,2 +0,0 @@ -line1 -line2 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual(FileChangeType.Delete, file.Type); Assert.AreEqual("test", file.From); Assert.AreEqual("/dev/null", file.To); var chunk = file.Chunks.First(); Assert.AreEqual("@@ -1,2 +0,0 @@", chunk.Content); Assert.AreEqual(2, chunk.Changes.Count()); var changes = chunk.Changes.ToArray(); Assert.AreEqual("line1", changes[0].Content); Assert.AreEqual("line2", changes[1].Content); }
public void ShouldParseDataSet108Diff() { string diff = DataSetHelper.ReadFileContent("D1709251127", "BinaryDiff.diff"); var files = DiffParserHelper.Parse(diff).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("/dev/null", file.From); Assert.AreEqual("Blog.db", file.To); Assert.AreEqual(FileChangeType.Modified, file.Type); }
public void ShouldParseFileNamesForNNewEmptyFile() { var diff = @" diff --git a/newFile.txt b/newFile.txt new file mode 100644 index 0000000..e6a2e28 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("/dev/null", file.From); Assert.AreEqual("newFile.txt", file.To); }
public void ShouldParseFileNamesForADeletedFile() { var diff = @" diff --git a/deletedFile.txt b/deletedFile.txt deleted file mode 100644 index e6a2e28..0000000 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("deletedFile.txt", file.From); Assert.AreEqual("/dev/null", file.To); }
public void ShouldParseDataSet1709251127Diff() { string diff = DataSetHelper.ReadFileContent("D1709251127", "Diff-b3a6303-781096c.diff"); var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; string expectedFileName = "DiffPatch.DiffParser/Diff.cs"; Assert.AreEqual(expectedFileName, file.From); Assert.AreEqual(expectedFileName, file.To); Assert.AreEqual(2, file.Chunks.Count()); }
public void ShouldPatchDataSet1709251127Diff() { string dataSetId = "D1709251127"; var diff = DataSetHelper.ReadFileContent(dataSetId, "Diff-b3a6303-781096c.diff"); FileDiff[] files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); FileDiff file = files[0]; string srcString = DataSetHelper.ReadFileContent(dataSetId, "Diff-b3a6303.txt"); string expectedString = DataSetHelper.ReadFileContent(dataSetId, "Diff-781096c.txt").Trim(); string patchedString = PatchHelper.Patch(srcString, file.Chunks, Environment.NewLine).Trim(); Assert.AreEqual(expectedString, patchedString); }
public void ShouldParseGnuSampleDiff() { var diff = @" --- lao 2002-02-21 23:30:39.942229878 -0800 +++ tzu 2002-02-21 23:30:50.442260588 -0800 @@ -1,7 +1,6 @@ -The Way that can be told of is not the eternal Way; -The name that can be named is not the eternal name. The Nameless is the origin of Heaven and Earth; -The Named is the mother of all things. +The named is the mother of all things. + Therefore let there always be non-being, so we may see their subtlety, And let there always be being, @@ -9,3 +8,6 @@ The two are the same, But after they are produced, they have different names. +They both may be called deep and profound. +Deeper and more profound, +The door of all subtleties! "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("lao", file.From); Assert.AreEqual("tzu", file.To); Assert.AreEqual(2, file.Chunks.Count()); var chunk0 = file.Chunks.ElementAt(0); Assert.AreEqual(1, chunk0.RangeInfo.OriginalRange.StartLine); Assert.AreEqual(7, chunk0.RangeInfo.OriginalRange.LineCount); Assert.AreEqual(1, chunk0.RangeInfo.NewRange.StartLine); Assert.AreEqual(6, chunk0.RangeInfo.NewRange.LineCount); var chunk1 = file.Chunks.ElementAt(1); Assert.AreEqual(9, chunk1.RangeInfo.OriginalRange.StartLine); Assert.AreEqual(3, chunk1.RangeInfo.OriginalRange.LineCount); Assert.AreEqual(8, chunk1.RangeInfo.NewRange.StartLine); Assert.AreEqual(6, chunk1.RangeInfo.NewRange.LineCount); }
public void ShouldParseDiffWithSingleLineFiles() { var diff = @" diff --git a/file1 b/file1 deleted file mode 100644 index db81be4..0000000 --- b/file1 +++ /dev/null @@ -1 +0,0 @@ -line1 diff --git a/file2 b/file2 new file mode 100644 index 0000000..db81be4 --- /dev/null +++ b/file2 @@ -0,0 +1 @@ +line1 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(2, files.Length); var file = files[0]; Assert.AreEqual(true, file.Deleted); Assert.AreEqual("file1", file.From); Assert.AreEqual("/dev/null", file.To); Assert.AreEqual("@@ -1 +0,0 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual(1, file.Chunks.ElementAt(0).Changes.Count()); Assert.AreEqual("line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.AreEqual(LineChangeType.Delete, file.Chunks.ElementAt(0).Changes.ElementAt(0).Type); file = files[1]; Assert.AreEqual(true, file.Add); Assert.AreEqual("/dev/null", file.From); Assert.AreEqual("file2", file.To); Assert.AreEqual("@@ -0,0 +1 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual(0, file.Chunks.ElementAt(0).RangeInfo.NewRange.LineCount); Assert.AreEqual(1, file.Chunks.ElementAt(0).Changes.Count()); Assert.AreEqual("line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.AreEqual(LineChangeType.Add, file.Chunks.ElementAt(0).Changes.ElementAt(0).Type); }
public void ShouldPatchSingleLine() { var diff = @" diff --git a/file b/file index 123..456 789 --- a/file +++ b/Facte @@ -1,2 +1,2 @@ - line1 + line2"; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); var file = files[0]; Assert.Single(file.Chunks); var chunk = file.Chunks.First(); var srcString = " line1\n line1a"; var expectedString = " line2\n line1a"; string patchedString = PatchHelper.Patch(srcString, new[] { chunk }, "\n"); Assert.Equal(expectedString, patchedString); }
public void ShouldParseMultipleFilesInDiff() { var diff = @" diff --git a/file1 b/file1 index 123..456 789 --- a/file1 +++ b/file1 @@ -1,2 +1,2 @@ - line1 + line2 diff --git a/file2 b/file2 index 123..456 789 --- a/file2 +++ b/file2 @@ -1,3 +1,3 @@ - line1 + line2 "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(2, files.Length); var file = files[0]; Assert.AreEqual("file1", file.From); Assert.AreEqual("file1", file.To); Assert.AreEqual("@@ -1,2 +1,2 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual(2, file.Chunks.ElementAt(0).Changes.Count()); Assert.AreEqual(" line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.AreEqual(" line2", file.Chunks.ElementAt(0).Changes.ElementAt(1).Content); file = files[1]; Assert.AreEqual("file2", file.From); Assert.AreEqual("file2", file.To); Assert.AreEqual("@@ -1,3 +1,3 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual(2, file.Chunks.ElementAt(0).Changes.Count()); Assert.AreEqual(" line1", file.Chunks.ElementAt(0).Changes.ElementAt(0).Content); Assert.AreEqual(" line2", file.Chunks.ElementAt(0).Changes.ElementAt(1).Content); }
public void ShouldParseHgDiffOutput() { var diff = @" diff -r 514fc757521e lib/parsers.coffee --- a/lib/parsers.coffee Thu Jul 09 00:56:36 2015 +0200 +++ b/lib/parsers.coffee Fri Jul 10 16:23:43 2015 +0200 @@ -43,6 +43,9 @@ files[file] = { added: added, deleted: deleted } files + diff: (out) -> + files = {} + module.exports = Parsers module.exports.version = (out) -> "; var files = DiffParserHelper.Parse(diff, Environment.NewLine).ToArray(); Assert.AreEqual(1, files.Length); var file = files[0]; Assert.AreEqual("@@ -43,6 +43,9 @@", file.Chunks.ElementAt(0).Content); Assert.AreEqual("lib/parsers.coffee", file.From); Assert.AreEqual("lib/parsers.coffee", file.To); }
static void Main(string[] args) { // args[0] is the path to Opus Magnum EXE string exe = args[0]; // args[1] is the path to mappings CSV string mappingsLoc = args[1]; // if there's a third string, its the path out.csv if(args.Length > 2) { Console.WriteLine("Reading strings..."); string[] lines = File.ReadAllLines(args[2]); bool hadSplit = true; // multi-line strings int lastIndex = 0; foreach(string line in lines) { string[] split = line.Split("~,~"); if(split.Length > 1) { // if we *can* split on this line, then we're definitely at the first line of a string hadSplit = true; try { lastIndex = int.Parse(split[0]); Strings.Add(lastIndex, split[1]); } catch(ArgumentException) { } } else if(!hadSplit) { // if this line isn't blank (or even if it is), then we're continuing a previous multi-line string, so append Strings[lastIndex] = Strings[lastIndex] + "\n" + line; } } // these are ridden with special characters // we can't just trim normally, see "fmt " breaking WAV loading // so we manually regex replace: [^a-zA-Z0-9_.:\n;'*()+<>\\{}# ,~/$\[\]\-©!"?&’\t=—@%●●●●…—……] is removed // this kills other languages, a better solution is needed in the future foreach(int key in Strings.Keys.ToList()) Strings[key] = Regex.Replace(Strings[key], "[^a-zA-Z0-9_.:\n;'*()+<>\\\\{}# ,~/$\\[\\]\\-©!\" ? &’\t =—@%●●●●…—……]", ""); } Console.WriteLine("Reading mappings..."); // for every line that doesn't start with a "#", split by "," and add to mappings string[] mappingsFile = File.ReadAllLines(mappingsLoc); foreach(var line in mappingsFile){ if(!line.StartsWith("#") && !line.Trim().Equals("")){ string[] split = line.Split(",", 2); mappings.Add(split[0], split[1]); } } var module = new PEFile(exe); var decompiler = new CSharpDecompiler(exe, new UniversalAssemblyResolver(exe, false, module.DetectTargetFrameworkId()), new DecompilerSettings() { NamedArguments = false }); // decompile Console.WriteLine("Decompiling..."); var ast = decompiler.DecompileWholeModuleAsSingleFile(); // we now have a syntax tree // we just need to walk it, modify class and member name references, and then output to files Console.WriteLine("Collecting intermediary names..."); ast.AcceptVisitor(new IdentifierCollectingVisitor()); Console.WriteLine("Remapping..."); ast.AcceptVisitor(new RemappingVisitor()); Console.WriteLine("Cleaning up invalid code..."); ast.AcceptVisitor(new CleanupVisitor()); // some params are in the wrong place... //Console.WriteLine("Adding modded entry point..."); //ast.AcceptVisitor(new EntrypointAddingVisitor()); Console.WriteLine("Writing nonsense -> intermediary..."); using StreamWriter intermediaryFile = new StreamWriter("./intermediary.txt"); foreach(KeyValuePair<string, string> kv in IdentifierCollectingVisitor.intermediary) { intermediaryFile.WriteLine(kv.Key + " -> " + kv.Value); } foreach(KeyValuePair<KeyValuePair<string, string>, string> kv in IdentifierCollectingVisitor.paramIntermediary) { intermediaryFile.WriteLine(kv.Key.Key + ", " + kv.Key.Value + " -> " + kv.Value); } string code = ast.ToString(); // if there's a fourth string, its the path to patch.diff // apply patch and compile if(args.Length > 3) { Console.WriteLine("Applying compilation patch..."); string patchFile = File.ReadAllText(args[3]); var diff = DiffParserHelper.Parse(patchFile); code = PatchHelper.Patch(code, diff.First().Chunks, "\n"); Console.WriteLine("Recompiling..."); SyntaxTree syntax = CSharpSyntaxTree.ParseText(code, new CSharpParseOptions()); var options = new CSharpCompilationOptions( OutputKind.WindowsApplication, optimizationLevel: OptimizationLevel.Release, allowUnsafe: true, warningLevel: 1, platform: Platform.X86 ); // File/Process/Directory doesn't exist var compilation = CSharpCompilation.Create("ModdedLightning", options: options) .AddReferences(new MetadataReference[]{ // add libs MetadataReference.CreateFromFile(typeof(string).Assembly.Location), MetadataReference.CreateFromFile(typeof(HashSet<object>).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), MetadataReference.CreateFromFile(Assembly.Load("mscorlib").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Runtime.Extensions").Location), MetadataReference.CreateFromFile(Assembly.Load("System.IO").Location), MetadataReference.CreateFromFile(Assembly.Load("System.IO.FileSystem").Location), MetadataReference.CreateFromFile(Assembly.Load("System.IO.FileSystem.Watcher").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Net.Requests").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Diagnostics.Process").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Private.Uri").Location), MetadataReference.CreateFromFile(Assembly.Load("System.ComponentModel.Primitives").Location), MetadataReference.CreateFromFile(Assembly.Load("System.Console").Location), MetadataReference.CreateFromFile(Assembly.Load("netstandard").Location), MetadataReference.CreateFromFile(typeof(Steamworks.CSteamID).Assembly.Location), MetadataReference.CreateFromFile(typeof(Ionic.Zip.ZipEntry).Assembly.Location) }) .AddSyntaxTrees(syntax); using FileStream outputAssembly = new FileStream("./ModdedLightning.exe", FileMode.Create); var res = compilation.Emit(outputAssembly); if(res.Success) { Console.WriteLine("Successfully recompiled!"); Console.WriteLine("(Press any key to continue.)"); Console.ReadKey(); Console.WriteLine("Writing runtime config & running batch..."); string runtimeConfig = @"{ ""runtimeOptions"": { ""tfm"": ""netcoreapp3.1"", ""framework"": { ""name"": ""Microsoft.NETCore.App"", ""version"": ""3.1.0"" }}}"; using StreamWriter configFile = new StreamWriter("./ModdedLightning.runtimeconfig.json"); configFile.WriteLine(runtimeConfig); string runBatch = @"""C:\Program Files (x86)\dotnet\dotnet.exe"" ModdedLightning.exe"; using StreamWriter batchFile = new StreamWriter("./runModded.bat"); batchFile.WriteLine(runBatch); } else { Console.WriteLine("Recompilation failed with " + res.Diagnostics.Length + " errors."); foreach(var error in res.Diagnostics) { Console.WriteLine("Location: " + error.Location.GetLineSpan()); Console.WriteLine(" " + error.GetMessage()); Console.WriteLine("(Press any key to continue.)"); Console.ReadKey(); } } } Console.WriteLine("Writing code output..."); using StreamWriter outputFile = new StreamWriter("./decomp.cs"); outputFile.WriteLine(code); Console.WriteLine("Done!"); }
public void ShouldParseNull() => Assert.Empty(DiffParserHelper.Parse(null));
public void ShouldParseEmptyString() => Assert.Empty(DiffParserHelper.Parse(string.Empty));
public void ShouldParseWhitespace() => Assert.Empty(DiffParserHelper.Parse(" "));
public void ShouldParseNull() => Assert.AreEqual(0, DiffParserHelper.Parse(null).Count());
public void ShouldParseEmptyString() => Assert.AreEqual(0, DiffParserHelper.Parse(string.Empty).Count());
public void ShouldParseWhitespace() => Assert.AreEqual(0, DiffParserHelper.Parse(" ").Count());