1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
package git2go
import (
"encoding/gob"
"errors"
"fmt"
"reflect"
)
func init() {
for typeToRegister := range registeredTypes {
gob.Register(reflect.Zero(typeToRegister).Interface())
}
}
var registeredTypes = map[reflect.Type]struct{}{
reflect.TypeOf(ChangeFileMode{}): {},
reflect.TypeOf(CreateDirectory{}): {},
reflect.TypeOf(CreateFile{}): {},
reflect.TypeOf(DeleteFile{}): {},
reflect.TypeOf(MoveFile{}): {},
reflect.TypeOf(UpdateFile{}): {},
reflect.TypeOf(wrapError{}): {},
reflect.TypeOf(IndexError{}): {},
reflect.TypeOf(UnknownIndexError("")): {},
reflect.TypeOf(InvalidArgumentError("")): {},
reflect.TypeOf(HasConflictsError{}): {},
reflect.TypeOf(ConflictingFilesError{}): {},
reflect.TypeOf(EmptyError{}): {},
reflect.TypeOf(UnknownIndexError("")): {},
reflect.TypeOf(ConflictError{}): {},
reflect.TypeOf(CommitNotFoundError{}): {},
}
// Result is the serialized result.
type Result struct {
// CommitID is the result of the call.
CommitID string
// Err is set if an error occurred. Err must exist on all gob serialized
// results so that all errors can be returned.
Err error
}
// wrapError is used to serialize wrapped errors as fmt.wrapError type only has
// private fields and can't be serialized via gob. It's also used to serialize unregistered
// error types by serializing only their error message.
type wrapError struct {
Message string
Err error
}
func (err wrapError) Error() string { return err.Message }
func (err wrapError) Unwrap() error { return err.Err }
// HasConflictsError is used when a change, for example a revert, could not be
// applied due to a conflict.
type HasConflictsError struct{}
func (err HasConflictsError) Error() string {
return "could not apply due to conflicts"
}
// ConflictingFilesError is an error raised when there are conflicting files.
type ConflictingFilesError struct {
// ConflictingFiles is the set of files which have conflicts.
ConflictingFiles []string
}
func (err ConflictingFilesError) Error() string {
return "there are conflicting files"
}
// EmptyError indicates the command, for example cherry-pick, did result in no
// changes, so the result is empty.
type EmptyError struct{}
func (err EmptyError) Error() string {
return "could not apply because the result was empty"
}
// CommitNotFoundError indicates that the given commit rev could not be found.
type CommitNotFoundError struct {
// Revision used to lookup the commit
Revision string
}
func (err CommitNotFoundError) Error() string {
return fmt.Sprintf("commit not found: %q", err.Revision)
}
// SerializableError returns an error that is Gob serializable.
// Registered types are serialized directly. Unregistered types
// are transformed in to an opaque error using their error message.
// Wrapped errors remain unwrappable.
func SerializableError(err error) error {
if err == nil {
return nil
}
if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil {
return wrapError{
Message: err.Error(),
Err: SerializableError(unwrappedErr),
}
}
if _, ok := registeredTypes[reflect.TypeOf(err)]; !ok {
return wrapError{Message: err.Error()}
}
return err
}
|