diff options
| author | 2026-06-06 21:51:58 +0000 | |
|---|---|---|
| committer | 2026-06-06 21:51:58 +0000 | |
| commit | 41e45d38f2d1ec78881f7e0ce778b2f43fed80a2 (patch) | |
| tree | 85378d19030bbc44e6fd22078a8fe7ac01c055f1 | |
| parent | ref: detached -> direct (diff) | |
| signature | No signature | |
ref/name, object: Simplify errors
| -rw-r--r-- | object/parse.go | 21 | ||||
| -rw-r--r-- | ref/name/component.go | 19 | ||||
| -rw-r--r-- | ref/name/errors.go | 14 | ||||
| -rw-r--r-- | ref/name/shorthand.go | 9 | ||||
| -rw-r--r-- | ref/name/update.go | 13 | ||||
| -rw-r--r-- | ref/name/validate.go | 10 |
6 files changed, 39 insertions, 47 deletions
diff --git a/object/parse.go b/object/parse.go index 9a7b9068..b488eb49 100644 --- a/object/parse.go +++ b/object/parse.go @@ -1,6 +1,7 @@ package object import ( + "errors" "fmt" "lindenii.org/go/furgit/object/blob" @@ -10,20 +11,10 @@ import ( "lindenii.org/go/furgit/object/typ" ) -// SizeMismatchError indicates a mismatch -// between the size expected from the object header -// and the size of the object. -type SizeMismatchError struct { - Expected uint64 - Got uint64 -} - -func (sizeMismatchError SizeMismatchError) Error() string { - return fmt.Sprintf( - "object: size mismatch: header says %d bytes, but got %d from body", - sizeMismatchError.Expected, sizeMismatchError.Got, - ) -} +// ErrSizeMismatch indicates a mismatch +// between the size declared in the object header +// and the size of the object body. +var ErrSizeMismatch = errors.New("object: size mismatch") // ParseWithHeader parses a loose object // in "type size\x00body" format. @@ -37,7 +28,7 @@ func ParseWithHeader(raw []byte, objectFormat id.ObjectFormat) (Object, error) { body := raw[headerLen:] if uint64(len(body)) != size { - return nil, SizeMismatchError{Expected: size, Got: uint64(len(body))} + return nil, fmt.Errorf("%w: header declares %d bytes, body has %d", ErrSizeMismatch, size, len(body)) } return ParseWithoutHeader(ty, body, objectFormat) diff --git a/ref/name/component.go b/ref/name/component.go index 40a736e2..b7d3bbb7 100644 --- a/ref/name/component.go +++ b/ref/name/component.go @@ -1,6 +1,9 @@ package name -import "strings" +import ( + "fmt" + "strings" +) const lockSuffix = ".lock" @@ -23,7 +26,7 @@ func nameDisposition(ch byte) byte { } } -func checkRefnameComponent(name string, flags *int, sanitized *strings.Builder, fullName string) (int, error) { +func checkRefnameComponent(name string, flags *int, sanitized *strings.Builder) (int, error) { var last byte var componentStart int @@ -47,7 +50,7 @@ func checkRefnameComponent(name string, flags *int, sanitized *strings.Builder, if sanitized != nil { truncateBuilder(sanitized, sanitized.Len()-1) } else { - return 0, &NameError{Name: fullName, Reason: "name contains '..'"} + return 0, fmt.Errorf("%w: name contains '..'", ErrInvalidName) } } case 3: @@ -55,21 +58,21 @@ func checkRefnameComponent(name string, flags *int, sanitized *strings.Builder, if sanitized != nil { overwriteBuilderAt(sanitized, sanitized.Len()-1) } else { - return 0, &NameError{Name: fullName, Reason: "name contains '@{'"} + return 0, fmt.Errorf("%w: name contains '@{'", ErrInvalidName) } } case 4: if sanitized != nil { overwriteBuilderAt(sanitized, sanitized.Len()-1) } else { - return 0, &NameError{Name: fullName, Reason: "name contains a forbidden character"} + return 0, fmt.Errorf("%w: name contains a forbidden character", ErrInvalidName) } case 5: if *flags&nameRefspecPattern == 0 { if sanitized != nil { overwriteBuilderAt(sanitized, sanitized.Len()-1) } else { - return 0, &NameError{Name: fullName, Reason: "name contains '*'"} + return 0, fmt.Errorf("%w: name contains '*'", ErrInvalidName) } } @@ -94,13 +97,13 @@ out: if sanitized != nil { overwriteBuilderAt(sanitized, componentStart) } else { - return 0, &NameError{Name: fullName, Reason: "component starts with '.'"} + return 0, fmt.Errorf("%w: component starts with '.'", ErrInvalidName) } } if componentLen >= len(lockSuffix) && name[componentLen-len(lockSuffix):componentLen] == lockSuffix { if sanitized == nil { - return 0, &NameError{Name: fullName, Reason: "component ends with .lock"} + return 0, fmt.Errorf("%w: component ends with .lock", ErrInvalidName) } for strings.HasSuffix(sanitized.String(), lockSuffix) { diff --git a/ref/name/errors.go b/ref/name/errors.go index 438c60aa..1011d518 100644 --- a/ref/name/errors.go +++ b/ref/name/errors.go @@ -1,14 +1,6 @@ package name -import "fmt" +import "errors" -// NameError reports an invalid reference name. -type NameError struct { - Name string - Reason string -} - -// Error implements error. -func (err *NameError) Error() string { - return fmt.Sprintf("ref/name: invalid name %q: %s", err.Name, err.Reason) -} +// ErrInvalidName indicates an invalid reference name. +var ErrInvalidName = errors.New("ref/name: invalid name") diff --git a/ref/name/shorthand.go b/ref/name/shorthand.go index 75d4854f..24142edb 100644 --- a/ref/name/shorthand.go +++ b/ref/name/shorthand.go @@ -1,6 +1,9 @@ package name -import "strings" +import ( + "fmt" + "strings" +) // Branch checks a branch shorthand // and returns its fully-qualified refs/heads/... name. @@ -10,7 +13,7 @@ import "strings" func Branch(name string) (string, error) { full := "refs/heads/" + name if strings.HasPrefix(name, "-") || full == "refs/heads/HEAD" { - return "", &NameError{Name: name, Reason: "invalid branch name"} + return "", fmt.Errorf("%w: invalid branch name", ErrInvalidName) } err := validate(full, 0) @@ -29,7 +32,7 @@ func Branch(name string) (string, error) { // and returns its fully-qualified refs/tags/... name. func Tag(name string) (string, error) { if strings.HasPrefix(name, "-") || name == "HEAD" { - return "", &NameError{Name: name, Reason: "invalid tag name"} + return "", fmt.Errorf("%w: invalid tag name", ErrInvalidName) } full := "refs/tags/" + name diff --git a/ref/name/update.go b/ref/name/update.go index d29afe4b..a87165a4 100644 --- a/ref/name/update.go +++ b/ref/name/update.go @@ -1,11 +1,14 @@ package name -import "strings" +import ( + "fmt" + "strings" +) // ValidateUpdateName checks whether name is valid for a direct ref update. func ValidateUpdateName(name string, hasNewValue bool) error { if IsPseudo(name) { - return &NameError{Name: name, Reason: "pseudoref updates are not allowed"} + return fmt.Errorf("%w: pseudoref updates are not allowed", ErrInvalidName) } if hasNewValue { @@ -13,7 +16,7 @@ func ValidateUpdateName(name string, hasNewValue bool) error { } if !IsSafe(name) { - return &NameError{Name: name, Reason: "unsafe name for update"} + return fmt.Errorf("%w: unsafe name for update", ErrInvalidName) } return nil @@ -23,7 +26,7 @@ func ValidateUpdateName(name string, hasNewValue bool) error { func ValidateSymbolicTarget(name string, target string) error { parsed := ParseWorktree(name) if parsed.BareRefName == "HEAD" && !strings.HasPrefix(target, "refs/heads/") { - return &NameError{Name: target, Reason: name + " must point to refs/heads/..."} + return fmt.Errorf("%w: %s must point to refs/heads/...", ErrInvalidName, name) } if IsRoot(target) { @@ -43,5 +46,5 @@ func ValidateSymbolicTarget(name string, target string) error { return nil } - return &NameError{Name: target, Reason: "symref target is not a ref"} + return fmt.Errorf("%w: symref target is not a ref", ErrInvalidName) } diff --git a/ref/name/validate.go b/ref/name/validate.go index 989858b1..2c524491 100644 --- a/ref/name/validate.go +++ b/ref/name/validate.go @@ -20,7 +20,7 @@ func checkOrSanitizeRefname(name string, flags int, sanitized *strings.Builder) if name == "@" { if sanitized == nil { - return &NameError{Name: name, Reason: "single @ is not allowed"} + return fmt.Errorf("%w: single @ is not allowed", ErrInvalidName) } sanitized.WriteByte('-') @@ -31,7 +31,7 @@ func checkOrSanitizeRefname(name string, flags int, sanitized *strings.Builder) sanitized.WriteByte('/') } - componentLen, err := checkRefnameComponent(remaining, &flags, sanitized, name) + componentLen, err := checkRefnameComponent(remaining, &flags, sanitized) switch { case sanitized != nil && componentLen == 0: case componentLen <= 0: @@ -39,7 +39,7 @@ func checkOrSanitizeRefname(name string, flags int, sanitized *strings.Builder) return err } - return &NameError{Name: name, Reason: "component has zero length"} + return fmt.Errorf("%w: component has zero length", ErrInvalidName) case err != nil: return err } @@ -56,12 +56,12 @@ func checkOrSanitizeRefname(name string, flags int, sanitized *strings.Builder) componentLen := len(remaining) if componentLen > 0 && remaining[componentLen-1] == '.' { if sanitized == nil { - return &NameError{Name: name, Reason: "name ends with '.'"} + return fmt.Errorf("%w: name ends with '.'", ErrInvalidName) } } if flags&nameAllowOneLevel == 0 && componentCount < 2 { - return &NameError{Name: name, Reason: "one-level name is not allowed"} + return fmt.Errorf("%w: one-level name is not allowed", ErrInvalidName) } return nil |
