From 0f639a5c35ba8494aa3d4791288b776c473b2501 Mon Sep 17 00:00:00 2001 From: Carmelo Messina Date: Sun, 23 Oct 2022 16:50:09 +0200 Subject: [PATCH] fix management of renamed files --- .../src/DiffPatch/Data/FileChangeType.cs | 12 +- DiffPatch/src/DiffPatch/DiffParser.cs | 378 +++++++++--------- SuperPatchUtils/Commands/BromiteRepo.cs | 22 +- 3 files changed, 217 insertions(+), 195 deletions(-) diff --git a/DiffPatch/src/DiffPatch/Data/FileChangeType.cs b/DiffPatch/src/DiffPatch/Data/FileChangeType.cs index ff525a8..74191aa 100644 --- a/DiffPatch/src/DiffPatch/Data/FileChangeType.cs +++ b/DiffPatch/src/DiffPatch/Data/FileChangeType.cs @@ -1,9 +1,9 @@ namespace DiffPatch.Data { - public enum FileChangeType - { - Modified = 0, - Add, - Delete - } + public enum FileChangeType + { + Modified = 0, + Add, + Delete + } } diff --git a/DiffPatch/src/DiffPatch/DiffParser.cs b/DiffPatch/src/DiffPatch/DiffParser.cs index 3c4abae..e09e142 100644 --- a/DiffPatch/src/DiffPatch/DiffParser.cs +++ b/DiffPatch/src/DiffPatch/DiffParser.cs @@ -7,27 +7,27 @@ namespace DiffPatch { - internal class DiffParser - { - const string noeol = "\\ No newline at end of file"; - const string devnull = "/dev/null"; + internal class DiffParser + { + const string noeol = "\\ No newline at end of file"; + const string devnull = "/dev/null"; - private delegate void ParserAction(string line, Match m); + private delegate void ParserAction(string line, Match m); - private List files = new List(); - private int in_del, in_add; + private List files = new List(); + private int in_del, in_add; - private Chunk current = null; - private FileDiff file = null; + private Chunk current = null; + private FileDiff file = null; - private int oldStart, newStart; - private int oldLines, newLines; + private int oldStart, newStart; + private int oldLines, newLines; - private readonly HandlerCollection schema; + private readonly HandlerCollection schema; - public DiffParser() - { - schema = new HandlerCollection + public DiffParser() + { + schema = new HandlerCollection { { @"^---", Ignore }, { @"^diff\s", Start }, @@ -39,209 +39,213 @@ public DiffParser() { @"^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@", Chunk }, { @"^-", DeleteLine }, { @"^\+", AddLine }, - { @"^Binary files (.+) and (.+) differ", BinaryDiff } - - }; - } - - public IEnumerable Run(IEnumerable lines) - { - foreach (var line in lines) - if (!ParseLine(line)) - ParseNormalLine(line); + { @"^Binary files (.+) and (.+) differ", BinaryDiff }, + { @"^rename to (.+)$", RenameFileTo }, + }; + } - return files; - } + public IEnumerable Run(IEnumerable lines) + { + foreach (var line in lines) + if (!ParseLine(line)) + ParseNormalLine(line); - private void Start(string line) - { - file = new FileDiff(); - files.Add(file); + return files; + } - if (file.To == null && file.From == null) - { - var fileNames = ParseFileNames(line); - - if (fileNames != null) - { - file.From = fileNames[0]; - file.To = fileNames[1]; - } - } - } + private void Start(string line) + { + file = new FileDiff(); + files.Add(file); - private void Restart() - { - if (file == null || file.Chunks.Count != 0) - Start(null); - } + if (file.To == null && file.From == null) + { + var fileNames = ParseFileNames(line); - private void NewFile() + if (fileNames != null) { - Restart(); - file.Type = FileChangeType.Add; - file.From = devnull; + file.From = fileNames[0]; + file.To = fileNames[1]; } + } + } - private void DeletedFile() - { - Restart(); - file.Type = FileChangeType.Delete; - file.To = devnull; - } + private void Restart() + { + if (file == null || file.Chunks.Count != 0) + Start(null); + } - private void Index(string line) - { - Restart(); - file.Index = line.Split(' ').Skip(1).ToList(); - } + private void NewFile() + { + Restart(); + file.Type = FileChangeType.Add; + file.From = devnull; + } - private void FromFile(string line) - { - Restart(); - file.From = ParseFileName(line); - } + private void DeletedFile() + { + Restart(); + file.Type = FileChangeType.Delete; + file.To = devnull; + } - private void ToFile(string line) - { - Restart(); - file.To = ParseFileName(line); - } + private void Index(string line) + { + Restart(); + file.Index = line.Split(' ').Skip(1).ToList(); + } - private void Ignore(string line) { } + private void FromFile(string line) + { + Restart(); + file.From = ParseFileName(line); + } - private void BinaryDiff() - { - Restart(); - file.Type = FileChangeType.Modified; - } + private void ToFile(string line) + { + Restart(); + file.To = ParseFileName(line); + } - private void Chunk(string line, Match match) - { - in_del = oldStart = int.Parse(match.Groups[1].Value); - oldLines = match.Groups[2].Success ? int.Parse(match.Groups[2].Value) : 0; - in_add = newStart = int.Parse(match.Groups[3].Value); - newLines = match.Groups[4].Success ? int.Parse(match.Groups[4].Value) : 0; - ChunkRangeInfo rangeInfo = new ChunkRangeInfo( - new ChunkRange(oldStart, oldLines), - new ChunkRange(newStart, newLines) - ); - - current = new Chunk(line, rangeInfo); - file.Chunks.Add(current); - } + private void Ignore(string line) { } - private void DeleteLine(string line) - { - string content = DiffLineHelper.GetContent(line); - current.Changes.Add(new LineDiff(type: LineChangeType.Delete, index: in_del++, content: content)); - file.Deletions++; - } + private void BinaryDiff() + { + Restart(); + file.Type = FileChangeType.Modified; + } - private void AddLine(string line) - { - string content = DiffLineHelper.GetContent(line); - current.Changes.Add(new LineDiff(type: LineChangeType.Add, index: in_add++, content: content)); - file.Additions++; - } + private void Chunk(string line, Match match) + { + in_del = oldStart = int.Parse(match.Groups[1].Value); + oldLines = match.Groups[2].Success ? int.Parse(match.Groups[2].Value) : 0; + in_add = newStart = int.Parse(match.Groups[3].Value); + newLines = match.Groups[4].Success ? int.Parse(match.Groups[4].Value) : 0; + ChunkRangeInfo rangeInfo = new ChunkRangeInfo( + new ChunkRange(oldStart, oldLines), + new ChunkRange(newStart, newLines) + ); + + current = new Chunk(line, rangeInfo); + file.Chunks.Add(current); + } + private void DeleteLine(string line) + { + string content = DiffLineHelper.GetContent(line); + current.Changes.Add(new LineDiff(type: LineChangeType.Delete, index: in_del++, content: content)); + file.Deletions++; + } - private void ParseNormalLine(string line) - { - if (file == null) return; + private void AddLine(string line) + { + string content = DiffLineHelper.GetContent(line); + current.Changes.Add(new LineDiff(type: LineChangeType.Add, index: in_add++, content: content)); + file.Additions++; + } - if (string.IsNullOrEmpty(line)) return; + private void RenameFileTo(string line, Match match) + { + file.Type = FileChangeType.Add; + } - string content = DiffLineHelper.GetContent(line); - current.Changes.Add(new LineDiff( - oldIndex: line == noeol ? 0 : in_del++, - newIndex: line == noeol ? 0 : in_add++, - content: content)); - } + private void ParseNormalLine(string line) + { + if (file == null) return; - private bool ParseLine(string line) - { - foreach (var p in schema) - { - var m = p.Expression.Match(line); - if (m.Success) - { - p.Action(line, m); - return true; - } - } - - return false; - } + if (string.IsNullOrEmpty(line)) return; - private static string[] ParseFileNames(string s) - { - if (string.IsNullOrEmpty(s)) return null; - return s - .Split(' ') - .Reverse().Take(2).Reverse() - .Select(fileName => Regex.Replace(fileName, @"^(a|b)\/", "")).ToArray(); - } + string content = DiffLineHelper.GetContent(line); + current.Changes.Add(new LineDiff( + oldIndex: line == noeol ? 0 : in_del++, + newIndex: line == noeol ? 0 : in_add++, + content: content)); + } - private static string ParseFileName(string s) + private bool ParseLine(string line) + { + foreach (var p in schema) + { + var m = p.Expression.Match(line); + if (m.Success) { - s = s.TrimStart('-', '+'); - s = s.Trim(); - - // ignore possible time stamp - var t = new Regex(@"\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d").Match(s); - if (t.Success) - { - s = s.Substring(0, t.Index).Trim(); - } - - // ignore git prefixes a/ or b/ - return Regex.IsMatch(s, @"^(a|b)\/") - ? s.Substring(2) - : s; + p.Action(line, m); + return true; } + } - private class HandlerRow - { - public HandlerRow(Regex expression, Action action) - { - Expression = expression; - Action = action; - } - - public Regex Expression { get; } - - public Action Action { get; } - } + return false; + } - private class HandlerCollection : IEnumerable - { - private List handlers = new List(); + private static string[] ParseFileNames(string s) + { + if (string.IsNullOrEmpty(s)) return null; + return s + .Split(' ') + .Reverse().Take(2).Reverse() + .Select(fileName => Regex.Replace(fileName, @"^(a|b)\/", "")).ToArray(); + } - public void Add(string expression, Action action) - { - handlers.Add(new HandlerRow(new Regex(expression), (line, m) => action())); - } + private static string ParseFileName(string s) + { + s = s.TrimStart('-', '+'); + s = s.Trim(); + + // ignore possible time stamp + var t = new Regex(@"\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d").Match(s); + if (t.Success) + { + s = s.Substring(0, t.Index).Trim(); + } + + // ignore git prefixes a/ or b/ + return Regex.IsMatch(s, @"^(a|b)\/") + ? s.Substring(2) + : s; + } - public void Add(string expression, Action action) - { - handlers.Add(new HandlerRow(new Regex(expression), (line, m) => action(line))); - } + private class HandlerRow + { + public HandlerRow(Regex expression, Action action) + { + Expression = expression; + Action = action; + } - public void Add(string expression, Action action) - { - handlers.Add(new HandlerRow(new Regex(expression), action)); - } + public Regex Expression { get; } - public IEnumerator GetEnumerator() - { - return handlers.GetEnumerator(); - } + public Action Action { get; } + } - IEnumerator IEnumerable.GetEnumerator() - { - return handlers.GetEnumerator(); - } - } + private class HandlerCollection : IEnumerable + { + private List handlers = new List(); + + public void Add(string expression, Action action) + { + handlers.Add(new HandlerRow(new Regex(expression), (line, m) => action())); + } + + public void Add(string expression, Action action) + { + handlers.Add(new HandlerRow(new Regex(expression), (line, m) => action(line))); + } + + public void Add(string expression, Action action) + { + handlers.Add(new HandlerRow(new Regex(expression), action)); + } + + public IEnumerator GetEnumerator() + { + return handlers.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return handlers.GetEnumerator(); + } } + } } diff --git a/SuperPatchUtils/Commands/BromiteRepo.cs b/SuperPatchUtils/Commands/BromiteRepo.cs index 22917f6..deacb9d 100644 --- a/SuperPatchUtils/Commands/BromiteRepo.cs +++ b/SuperPatchUtils/Commands/BromiteRepo.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.CommandLine; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; @@ -8,6 +9,7 @@ using DiffPatch.Data; using SuperPatch.Core; +using SuperPatch.Core.Status; using SuperPatch.Core.Storages; using SuperPatch.Core.Storages.Bromite; using SuperPatchUtils.Commands.Utils; @@ -24,15 +26,31 @@ internal static IEnumerable GetCommands() new Argument("commitshaortag", "Bromite Commit hash"), new Argument("outputdir", "The output directory"), new Option("--verbose", "Verbose mode"), + new Option("--createpatched", "Verbose mode"), + new Argument("patchdir", "The patched output directory"), }.WithHandler(typeof(BromiteRepo), nameof(Commands.BromiteRepo.DownloadRepoAsync)) }; } private static async Task DownloadRepoAsync( - string commitshaortag, string outputdir, bool verbose, + string commitshaortag, string outputdir, string patchdir, + bool verbose, bool createpatched, IConsole console, CancellationToken cancellationToken) { - await DownloadAsync(commitshaortag, outputdir, verbose, console, cancellationToken); + if (createpatched && !System.IO.Directory.Exists(patchdir)) + { + console.Error.Write($"Error: directory {createpatched} doesn't exists"); + return 1; + } + + var wrkBromite = + await DownloadAsync(commitshaortag, outputdir, verbose, console, cancellationToken); + + if (createpatched) + { + await Commons.PatchFiles(wrkBromite, patchdir, console, + new SuperPatch.Core.Status.StatusDelegate()); + } return 0; }