diff options
Diffstat (limited to 'internal/gitdiff/apply.go')
| -rw-r--r-- | internal/gitdiff/apply.go | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/internal/gitdiff/apply.go b/internal/gitdiff/apply.go deleted file mode 100644 index 44bbcca..0000000 --- a/internal/gitdiff/apply.go +++ /dev/null @@ -1,147 +0,0 @@ -package gitdiff - -import ( - "errors" - "fmt" - "io" - "sort" -) - -// Conflict indicates an apply failed due to a conflict between the patch and -// the source content. -// -// Users can test if an error was caused by a conflict by using errors.Is with -// an empty Conflict: -// -// if errors.Is(err, &Conflict{}) { -// // handle conflict -// } -type Conflict struct { - msg string -} - -func (c *Conflict) Error() string { - return "conflict: " + c.msg -} - -// Is implements error matching for Conflict. Passing an empty instance of -// Conflict always returns true. -func (c *Conflict) Is(other error) bool { - if other, ok := other.(*Conflict); ok { - return other.msg == "" || other.msg == c.msg - } - return false -} - -// ApplyError wraps an error that occurs during patch application with -// additional location information, if it is available. -type ApplyError struct { - // Line is the one-indexed line number in the source data - Line int64 - // Fragment is the one-indexed fragment number in the file - Fragment int - // FragmentLine is the one-indexed line number in the fragment - FragmentLine int - - err error -} - -// Unwrap returns the wrapped error. -func (e *ApplyError) Unwrap() error { - return e.err -} - -func (e *ApplyError) Error() string { - return fmt.Sprintf("%v", e.err) -} - -type lineNum int -type fragNum int -type fragLineNum int - -// applyError creates a new *ApplyError wrapping err or augments the information -// in err with args if it is already an *ApplyError. Returns nil if err is nil. -func applyError(err error, args ...interface{}) error { - if err == nil { - return nil - } - - e, ok := err.(*ApplyError) - if !ok { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - e = &ApplyError{err: err} - } - for _, arg := range args { - switch v := arg.(type) { - case lineNum: - e.Line = int64(v) + 1 - case fragNum: - e.Fragment = int(v) + 1 - case fragLineNum: - e.FragmentLine = int(v) + 1 - } - } - return e -} - -var ( - errApplyInProgress = errors.New("gitdiff: incompatible apply in progress") - errApplierClosed = errors.New("gitdiff: applier is closed") -) - -// Apply applies the changes in f to src, writing the result to dst. It can -// apply both text and binary changes. -// -// If an error occurs while applying, Apply returns an *ApplyError that -// annotates the error with additional information. If the error is because of -// a conflict with the source, the wrapped error will be a *Conflict. -func Apply(dst io.Writer, src io.ReaderAt, f *File) error { - if f.IsBinary { - if len(f.TextFragments) > 0 { - return applyError(errors.New("binary file contains text fragments")) - } - if f.BinaryFragment == nil { - return applyError(errors.New("binary file does not contain a binary fragment")) - } - } else { - if f.BinaryFragment != nil { - return applyError(errors.New("text file contains a binary fragment")) - } - } - - switch { - case f.BinaryFragment != nil: - applier := NewBinaryApplier(dst, src) - if err := applier.ApplyFragment(f.BinaryFragment); err != nil { - return err - } - return applier.Close() - - case len(f.TextFragments) > 0: - frags := make([]*TextFragment, len(f.TextFragments)) - copy(frags, f.TextFragments) - - sort.Slice(frags, func(i, j int) bool { - return frags[i].OldPosition < frags[j].OldPosition - }) - - // TODO(bkeyes): consider merging overlapping fragments - // right now, the application fails if fragments overlap, but it should be - // possible to precompute the result of applying them in order - - applier := NewTextApplier(dst, src) - for i, frag := range frags { - if err := applier.ApplyFragment(frag); err != nil { - return applyError(err, fragNum(i)) - } - } - return applier.Close() - - default: - // nothing to apply, just copy all the data - _, err := copyFrom(dst, src, 0) - return err - } -} |
