Exemple #1
0
 public ClassifiedDiff(DiffMatchPatch.Diff diff, DiffClassification classification)
 {
     Diff = diff;
     Classification = classification;
 }
Exemple #2
0
        /// <summary>
        /// Writes a difference summary to the file system.
        /// </summary>
        /// <param name="differences">The differences.</param>
        /// <param name="referenceDatabase">Reference database definition</param>
        /// <param name="targetDatabase">Target database to update</param>
        public static void WriteDifferenceSummary(DBTypes.Database referenceDatabase, DBTypes.Database targetDatabase, DifferenceSet differences)
        {
            StreamWriter diffWriter = new StreamWriter(Path.Combine(RunOptions.Current.ScriptOutputDirectory, RunOptions.Current.DiffFile), false);

            var patchGenerator = new DiffMatchPatch.diff_match_patch();

            foreach (var difference in differences)
            {
                if (difference.DifferenceType != DifferenceType.Modified)
                {
                    continue;
                }

                diffWriter.WriteLine(difference.ToString());
                diffWriter.WriteLine();

                var referenceDefinition = referenceDatabase[difference.Item].GenerateCreateScript();
                var targetDefinition    = targetDatabase[difference.Item].GenerateCreateScript();
                var diff = patchGenerator.diff_main(targetDefinition.Text, referenceDefinition.Text);
                //var patch = patchGenerator.diff_prettyHtml(diff);
                //patch = System.Web.HttpUtility.UrlDecode(patch);
                //diffWriter.WriteLine(patch);

                //Diffs aren't full lines...  we need to fix that for readability
                var coalesced = new List <DiffMatchPatch.Diff>();
                DiffMatchPatch.Diff lastEqual  = null;
                DiffMatchPatch.Diff lastInsert = null;
                DiffMatchPatch.Diff lastDelete = null;
                foreach (var entry in diff)
                {
                    if (entry.operation == DiffMatchPatch.Operation.INSERT)
                    {
                        lastInsert       = lastInsert ?? new DiffMatchPatch.Diff(entry.operation, "");
                        lastInsert.text += entry.text;
                    }
                    else if (entry.operation == DiffMatchPatch.Operation.DELETE)
                    {
                        lastDelete       = lastDelete ?? new DiffMatchPatch.Diff(entry.operation, "");
                        lastDelete.text += entry.text;
                    }
                    else if (entry.operation == DiffMatchPatch.Operation.EQUAL)
                    {
                        string content   = entry.text;
                        int    linebreak = content.IndexOf("\n");
                        string donate    = linebreak < 0 ? content : content.Substring(0, linebreak + 1);

                        //see if there's a change that needs this to finish its line
                        bool used = false;
                        if (lastInsert != null)
                        {
                            lastInsert.text += donate;
                            used             = true;
                        }
                        if (lastDelete != null)
                        {
                            lastDelete.text += donate;
                            used             = true;
                        }

                        if (used)
                        {
                            content = content.Remove(0, donate.Length);
                        }

                        //stash anything that's left
                        if (content.Length > 0)
                        {
                            //time to flush everything we've coalesced

                            //see if there are any mods that need to grab a line start
                            if (lastEqual != null && !lastEqual.text.EndsWith("\n") && (lastInsert != null || lastDelete != null))
                            {
                                linebreak      = lastEqual.text.LastIndexOf("\n");
                                donate         = lastEqual.text.Substring(linebreak + 1);
                                lastEqual.text = lastEqual.text.Remove(linebreak + 1);

                                if (lastInsert != null)
                                {
                                    lastInsert.text = donate + lastInsert.text;
                                }
                                if (lastDelete != null)
                                {
                                    lastDelete.text = donate + lastDelete.text;
                                }
                            }

                            //do the flush
                            if (lastEqual != null)
                            {
                                coalesced.Add(lastEqual);
                                lastEqual = null;
                            }
                            if (lastInsert != null)
                            {
                                coalesced.Add(lastInsert);
                                lastInsert = null;
                            }
                            if (lastDelete != null)
                            {
                                coalesced.Add(lastDelete);
                                lastDelete = null;
                            }

                            lastEqual = new DiffMatchPatch.Diff(DiffMatchPatch.Operation.EQUAL, content);
                        }
                    }
                    else
                    {
                        throw new Exception("Unknown operation: " + entry.operation);
                    }
                }
                if (lastEqual != null)
                {
                    coalesced.Add(lastEqual);
                }
                if (lastInsert != null)
                {
                    coalesced.Add(lastInsert);
                }
                if (lastDelete != null)
                {
                    coalesced.Add(lastDelete);
                }

                //Finally spit out a nice diff
                for (int i = 0; i < coalesced.Count; i++)
                {
                    var entry = coalesced[i];
                    if (entry.operation == DiffMatchPatch.Operation.EQUAL)
                    {
                        //(ab)use a stream to partition the content into lines
                        using (var text = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(entry.text))))
                        {
                            //write out the first two lines
                            if (i > 0)
                            {
                                for (int j = 0; j < 2 && !text.EndOfStream; j++)
                                {
                                    string line = text.ReadLine();
                                    if (string.IsNullOrEmpty(line))
                                    {
                                        j--;
                                        continue;
                                    }

                                    diffWriter.WriteLine(line);
                                }
                            }

                            //write out the last two lines
                            if (i < coalesced.Count - 1 && !text.EndOfStream)
                            {
                                var lines = new string[3];
                                while (!text.EndOfStream)
                                {
                                    lines[0] = lines[1];
                                    lines[1] = lines[2];
                                    lines[2] = text.ReadLine();
                                }

                                if (i > 0 && lines[0] != null)
                                {
                                    diffWriter.WriteLine();
                                    diffWriter.WriteLine(">> ... <<");
                                    diffWriter.WriteLine();
                                }

                                if (lines[1] != null)
                                {
                                    diffWriter.WriteLine(lines[1]);
                                }
                                diffWriter.WriteLine(lines[2]);
                            }
                        }
                    }
                    else
                    {
                        string marker = entry.operation == DiffMatchPatch.Operation.INSERT ? "> > > >" : "< < < <";
                        diffWriter.WriteLine(marker);
                        diffWriter.Write(entry.text);
                        if (!entry.text.EndsWith("\n"))
                        {
                            diffWriter.WriteLine();
                        }
                        diffWriter.WriteLine(marker);
                    }
                }
                diffWriter.WriteLine();
            }

            diffWriter.Close();
        }