Compare two sequences of lines; generate the delta as a unified diff. Unified diffs are a compact way of showing line changes and a few lines of context. The number of context lines is set by 'n' which defaults to three. By default, the diff control lines (those with ---, +++, or @@) are created
(writer io.Writer, diff UnifiedDiff)
| 560 | // 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. |
| 561 | // The modification times are normally expressed in the ISO 8601 format. |
| 562 | func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { |
| 563 | buf := bufio.NewWriter(writer) |
| 564 | defer buf.Flush() |
| 565 | wf := func(format string, args ...interface{}) error { |
| 566 | _, err := buf.WriteString(fmt.Sprintf(format, args...)) |
| 567 | return err |
| 568 | } |
| 569 | ws := func(s string) error { |
| 570 | _, err := buf.WriteString(s) |
| 571 | return err |
| 572 | } |
| 573 | |
| 574 | if len(diff.Eol) == 0 { |
| 575 | diff.Eol = "\n" |
| 576 | } |
| 577 | |
| 578 | started := false |
| 579 | m := NewMatcher(diff.A, diff.B) |
| 580 | for _, g := range m.GetGroupedOpCodes(diff.Context) { |
| 581 | if !started { |
| 582 | started = true |
| 583 | fromDate := "" |
| 584 | if len(diff.FromDate) > 0 { |
| 585 | fromDate = "\t" + diff.FromDate |
| 586 | } |
| 587 | toDate := "" |
| 588 | if len(diff.ToDate) > 0 { |
| 589 | toDate = "\t" + diff.ToDate |
| 590 | } |
| 591 | if diff.FromFile != "" || diff.ToFile != "" { |
| 592 | err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) |
| 593 | if err != nil { |
| 594 | return err |
| 595 | } |
| 596 | err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) |
| 597 | if err != nil { |
| 598 | return err |
| 599 | } |
| 600 | } |
| 601 | } |
| 602 | first, last := g[0], g[len(g)-1] |
| 603 | range1 := formatRangeUnified(first.I1, last.I2) |
| 604 | range2 := formatRangeUnified(first.J1, last.J2) |
| 605 | if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { |
| 606 | return err |
| 607 | } |
| 608 | for _, c := range g { |
| 609 | i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 |
| 610 | if c.Tag == 'e' { |
| 611 | for _, line := range diff.A[i1:i2] { |
| 612 | if err := ws(" " + line); err != nil { |
| 613 | return err |
| 614 | } |
| 615 | } |
| 616 | continue |
| 617 | } |
| 618 | if c.Tag == 'r' || c.Tag == 'd' { |
| 619 | for _, line := range diff.A[i1:i2] { |
no test coverage detected
searching dependent graphs…