feat(dir2config): defaults
This commit is contained in:
58
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/diff/patch.go
generated
vendored
Normal file
58
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/diff/patch.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/filemode"
|
||||
)
|
||||
|
||||
// Operation defines the operation of a diff item.
|
||||
type Operation int
|
||||
|
||||
const (
|
||||
// Equal item represents a equals diff.
|
||||
Equal Operation = iota
|
||||
// Add item represents an insert diff.
|
||||
Add
|
||||
// Delete item represents a delete diff.
|
||||
Delete
|
||||
)
|
||||
|
||||
// Patch represents a collection of steps to transform several files.
|
||||
type Patch interface {
|
||||
// FilePatches returns a slice of patches per file.
|
||||
FilePatches() []FilePatch
|
||||
// Message returns an optional message that can be at the top of the
|
||||
// Patch representation.
|
||||
Message() string
|
||||
}
|
||||
|
||||
// FilePatch represents the necessary steps to transform one file to another.
|
||||
type FilePatch interface {
|
||||
// IsBinary returns true if this patch is representing a binary file.
|
||||
IsBinary() bool
|
||||
// Files returns the from and to Files, with all the necessary metadata to
|
||||
// about them. If the patch creates a new file, "from" will be nil.
|
||||
// If the patch deletes a file, "to" will be nil.
|
||||
Files() (from, to File)
|
||||
// Chunks returns a slice of ordered changes to transform "from" File to
|
||||
// "to" File. If the file is a binary one, Chunks will be empty.
|
||||
Chunks() []Chunk
|
||||
}
|
||||
|
||||
// File contains all the file metadata necessary to print some patch formats.
|
||||
type File interface {
|
||||
// Hash returns the File Hash.
|
||||
Hash() plumbing.Hash
|
||||
// Mode returns the FileMode.
|
||||
Mode() filemode.FileMode
|
||||
// Path returns the complete Path to the file, including the filename.
|
||||
Path() string
|
||||
}
|
||||
|
||||
// Chunk represents a portion of a file transformation to another.
|
||||
type Chunk interface {
|
||||
// Content contains the portion of the file.
|
||||
Content() string
|
||||
// Type contains the Operation to do with this Chunk.
|
||||
Type() Operation
|
||||
}
|
360
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/diff/unified_encoder.go
generated
vendored
Normal file
360
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/diff/unified_encoder.go
generated
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
)
|
||||
|
||||
const (
|
||||
diffInit = "diff --git a/%s b/%s\n"
|
||||
|
||||
chunkStart = "@@ -"
|
||||
chunkMiddle = " +"
|
||||
chunkEnd = " @@%s\n"
|
||||
chunkCount = "%d,%d"
|
||||
|
||||
noFilePath = "/dev/null"
|
||||
aDir = "a/"
|
||||
bDir = "b/"
|
||||
|
||||
fPath = "--- %s\n"
|
||||
tPath = "+++ %s\n"
|
||||
binary = "Binary files %s and %s differ\n"
|
||||
|
||||
addLine = "+%s\n"
|
||||
deleteLine = "-%s\n"
|
||||
equalLine = " %s\n"
|
||||
|
||||
oldMode = "old mode %o\n"
|
||||
newMode = "new mode %o\n"
|
||||
deletedFileMode = "deleted file mode %o\n"
|
||||
newFileMode = "new file mode %o\n"
|
||||
|
||||
renameFrom = "from"
|
||||
renameTo = "to"
|
||||
renameFileMode = "rename %s %s\n"
|
||||
|
||||
indexAndMode = "index %s..%s %o\n"
|
||||
indexNoMode = "index %s..%s\n"
|
||||
|
||||
DefaultContextLines = 3
|
||||
)
|
||||
|
||||
// UnifiedEncoder encodes an unified diff into the provided Writer.
|
||||
// There are some unsupported features:
|
||||
// - Similarity index for renames
|
||||
// - Sort hash representation
|
||||
type UnifiedEncoder struct {
|
||||
io.Writer
|
||||
|
||||
// ctxLines is the count of unchanged lines that will appear
|
||||
// surrounding a change.
|
||||
ctxLines int
|
||||
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
func NewUnifiedEncoder(w io.Writer, ctxLines int) *UnifiedEncoder {
|
||||
return &UnifiedEncoder{ctxLines: ctxLines, Writer: w}
|
||||
}
|
||||
|
||||
func (e *UnifiedEncoder) Encode(patch Patch) error {
|
||||
e.printMessage(patch.Message())
|
||||
|
||||
if err := e.encodeFilePatch(patch.FilePatches()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := e.buf.WriteTo(e)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *UnifiedEncoder) encodeFilePatch(filePatches []FilePatch) error {
|
||||
for _, p := range filePatches {
|
||||
f, t := p.Files()
|
||||
if err := e.header(f, t, p.IsBinary()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g := newHunksGenerator(p.Chunks(), e.ctxLines)
|
||||
for _, c := range g.Generate() {
|
||||
c.WriteTo(&e.buf)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *UnifiedEncoder) printMessage(message string) {
|
||||
isEmpty := message == ""
|
||||
hasSuffix := strings.HasSuffix(message, "\n")
|
||||
if !isEmpty && !hasSuffix {
|
||||
message = message + "\n"
|
||||
}
|
||||
|
||||
e.buf.WriteString(message)
|
||||
}
|
||||
|
||||
func (e *UnifiedEncoder) header(from, to File, isBinary bool) error {
|
||||
switch {
|
||||
case from == nil && to == nil:
|
||||
return nil
|
||||
case from != nil && to != nil:
|
||||
hashEquals := from.Hash() == to.Hash()
|
||||
|
||||
fmt.Fprintf(&e.buf, diffInit, from.Path(), to.Path())
|
||||
|
||||
if from.Mode() != to.Mode() {
|
||||
fmt.Fprintf(&e.buf, oldMode+newMode, from.Mode(), to.Mode())
|
||||
}
|
||||
|
||||
if from.Path() != to.Path() {
|
||||
fmt.Fprintf(&e.buf,
|
||||
renameFileMode+renameFileMode,
|
||||
renameFrom, from.Path(), renameTo, to.Path())
|
||||
}
|
||||
|
||||
if from.Mode() != to.Mode() && !hashEquals {
|
||||
fmt.Fprintf(&e.buf, indexNoMode, from.Hash(), to.Hash())
|
||||
} else if !hashEquals {
|
||||
fmt.Fprintf(&e.buf, indexAndMode, from.Hash(), to.Hash(), from.Mode())
|
||||
}
|
||||
|
||||
if !hashEquals {
|
||||
e.pathLines(isBinary, aDir+from.Path(), bDir+to.Path())
|
||||
}
|
||||
case from == nil:
|
||||
fmt.Fprintf(&e.buf, diffInit, to.Path(), to.Path())
|
||||
fmt.Fprintf(&e.buf, newFileMode, to.Mode())
|
||||
fmt.Fprintf(&e.buf, indexNoMode, plumbing.ZeroHash, to.Hash())
|
||||
e.pathLines(isBinary, noFilePath, bDir+to.Path())
|
||||
case to == nil:
|
||||
fmt.Fprintf(&e.buf, diffInit, from.Path(), from.Path())
|
||||
fmt.Fprintf(&e.buf, deletedFileMode, from.Mode())
|
||||
fmt.Fprintf(&e.buf, indexNoMode, from.Hash(), plumbing.ZeroHash)
|
||||
e.pathLines(isBinary, aDir+from.Path(), noFilePath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *UnifiedEncoder) pathLines(isBinary bool, fromPath, toPath string) {
|
||||
format := fPath + tPath
|
||||
if isBinary {
|
||||
format = binary
|
||||
}
|
||||
|
||||
fmt.Fprintf(&e.buf, format, fromPath, toPath)
|
||||
}
|
||||
|
||||
type hunksGenerator struct {
|
||||
fromLine, toLine int
|
||||
ctxLines int
|
||||
chunks []Chunk
|
||||
current *hunk
|
||||
hunks []*hunk
|
||||
beforeContext, afterContext []string
|
||||
}
|
||||
|
||||
func newHunksGenerator(chunks []Chunk, ctxLines int) *hunksGenerator {
|
||||
return &hunksGenerator{
|
||||
chunks: chunks,
|
||||
ctxLines: ctxLines,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *hunksGenerator) Generate() []*hunk {
|
||||
for i, chunk := range c.chunks {
|
||||
ls := splitLines(chunk.Content())
|
||||
lsLen := len(ls)
|
||||
|
||||
switch chunk.Type() {
|
||||
case Equal:
|
||||
c.fromLine += lsLen
|
||||
c.toLine += lsLen
|
||||
c.processEqualsLines(ls, i)
|
||||
case Delete:
|
||||
if lsLen != 0 {
|
||||
c.fromLine++
|
||||
}
|
||||
|
||||
c.processHunk(i, chunk.Type())
|
||||
c.fromLine += lsLen - 1
|
||||
c.current.AddOp(chunk.Type(), ls...)
|
||||
case Add:
|
||||
if lsLen != 0 {
|
||||
c.toLine++
|
||||
}
|
||||
c.processHunk(i, chunk.Type())
|
||||
c.toLine += lsLen - 1
|
||||
c.current.AddOp(chunk.Type(), ls...)
|
||||
}
|
||||
|
||||
if i == len(c.chunks)-1 && c.current != nil {
|
||||
c.hunks = append(c.hunks, c.current)
|
||||
}
|
||||
}
|
||||
|
||||
return c.hunks
|
||||
}
|
||||
|
||||
func (c *hunksGenerator) processHunk(i int, op Operation) {
|
||||
if c.current != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var ctxPrefix string
|
||||
linesBefore := len(c.beforeContext)
|
||||
if linesBefore > c.ctxLines {
|
||||
ctxPrefix = " " + c.beforeContext[linesBefore-c.ctxLines-1]
|
||||
c.beforeContext = c.beforeContext[linesBefore-c.ctxLines:]
|
||||
linesBefore = c.ctxLines
|
||||
}
|
||||
|
||||
c.current = &hunk{ctxPrefix: ctxPrefix}
|
||||
c.current.AddOp(Equal, c.beforeContext...)
|
||||
|
||||
switch op {
|
||||
case Delete:
|
||||
c.current.fromLine, c.current.toLine =
|
||||
c.addLineNumbers(c.fromLine, c.toLine, linesBefore, i, Add)
|
||||
case Add:
|
||||
c.current.toLine, c.current.fromLine =
|
||||
c.addLineNumbers(c.toLine, c.fromLine, linesBefore, i, Delete)
|
||||
}
|
||||
|
||||
c.beforeContext = nil
|
||||
}
|
||||
|
||||
// addLineNumbers obtains the line numbers in a new chunk
|
||||
func (c *hunksGenerator) addLineNumbers(la, lb int, linesBefore int, i int, op Operation) (cla, clb int) {
|
||||
cla = la - linesBefore
|
||||
// we need to search for a reference for the next diff
|
||||
switch {
|
||||
case linesBefore != 0 && c.ctxLines != 0:
|
||||
if lb > c.ctxLines {
|
||||
clb = lb - c.ctxLines + 1
|
||||
} else {
|
||||
clb = 1
|
||||
}
|
||||
case c.ctxLines == 0:
|
||||
clb = lb
|
||||
case i != len(c.chunks)-1:
|
||||
next := c.chunks[i+1]
|
||||
if next.Type() == op || next.Type() == Equal {
|
||||
// this diff will be into this chunk
|
||||
clb = lb + 1
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *hunksGenerator) processEqualsLines(ls []string, i int) {
|
||||
if c.current == nil {
|
||||
c.beforeContext = append(c.beforeContext, ls...)
|
||||
return
|
||||
}
|
||||
|
||||
c.afterContext = append(c.afterContext, ls...)
|
||||
if len(c.afterContext) <= c.ctxLines*2 && i != len(c.chunks)-1 {
|
||||
c.current.AddOp(Equal, c.afterContext...)
|
||||
c.afterContext = nil
|
||||
} else {
|
||||
ctxLines := c.ctxLines
|
||||
if ctxLines > len(c.afterContext) {
|
||||
ctxLines = len(c.afterContext)
|
||||
}
|
||||
c.current.AddOp(Equal, c.afterContext[:ctxLines]...)
|
||||
c.hunks = append(c.hunks, c.current)
|
||||
|
||||
c.current = nil
|
||||
c.beforeContext = c.afterContext[ctxLines:]
|
||||
c.afterContext = nil
|
||||
}
|
||||
}
|
||||
|
||||
func splitLines(s string) []string {
|
||||
out := strings.Split(s, "\n")
|
||||
if out[len(out)-1] == "" {
|
||||
out = out[:len(out)-1]
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type hunk struct {
|
||||
fromLine int
|
||||
toLine int
|
||||
|
||||
fromCount int
|
||||
toCount int
|
||||
|
||||
ctxPrefix string
|
||||
ops []*op
|
||||
}
|
||||
|
||||
func (c *hunk) WriteTo(buf *bytes.Buffer) {
|
||||
buf.WriteString(chunkStart)
|
||||
|
||||
if c.fromCount == 1 {
|
||||
fmt.Fprintf(buf, "%d", c.fromLine)
|
||||
} else {
|
||||
fmt.Fprintf(buf, chunkCount, c.fromLine, c.fromCount)
|
||||
}
|
||||
|
||||
buf.WriteString(chunkMiddle)
|
||||
|
||||
if c.toCount == 1 {
|
||||
fmt.Fprintf(buf, "%d", c.toLine)
|
||||
} else {
|
||||
fmt.Fprintf(buf, chunkCount, c.toLine, c.toCount)
|
||||
}
|
||||
|
||||
fmt.Fprintf(buf, chunkEnd, c.ctxPrefix)
|
||||
|
||||
for _, d := range c.ops {
|
||||
buf.WriteString(d.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *hunk) AddOp(t Operation, s ...string) {
|
||||
ls := len(s)
|
||||
switch t {
|
||||
case Add:
|
||||
c.toCount += ls
|
||||
case Delete:
|
||||
c.fromCount += ls
|
||||
case Equal:
|
||||
c.toCount += ls
|
||||
c.fromCount += ls
|
||||
}
|
||||
|
||||
for _, l := range s {
|
||||
c.ops = append(c.ops, &op{l, t})
|
||||
}
|
||||
}
|
||||
|
||||
type op struct {
|
||||
text string
|
||||
t Operation
|
||||
}
|
||||
|
||||
func (o *op) String() string {
|
||||
var prefix string
|
||||
switch o.t {
|
||||
case Add:
|
||||
prefix = addLine
|
||||
case Delete:
|
||||
prefix = deleteLine
|
||||
case Equal:
|
||||
prefix = equalLine
|
||||
}
|
||||
|
||||
return fmt.Sprintf(prefix, o.text)
|
||||
}
|
Reference in New Issue
Block a user