precommit

package
v0.0.0-...-97ebc44 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrMissingSentinel     = errors.New("missing required sentinel error")
	ErrTrailingKey         = errors.New("trailing key without value")
	ErrMisplacedError      = errors.New("error in wrong position")
	ErrInvalidArgumentType = errors.New("invalid argument type")
	ErrOddKeyValueCount    = errors.New("odd number of key-value arguments")
	ErrCrossPackageError   = errors.New("error from different doterr package")
)

Sentinel errors for validation failures

View Source
var (
	// ErrPrecommit is the base sentinel for all precommit package errors
	ErrPrecommit = errors.New("precommit error")

	// ErrCacheNotFound indicates no cached analysis results exist
	ErrCacheNotFound = errors.New("cache not found")
)

Sentinel errors for the precommit package

Functions

func AppendErr

func AppendErr(errs []error, err error) []error

func ClearPersistedResult

func ClearPersistedResult(cacheKey string) (err error)

ClearPersistedResult removes cached analysis results

func CombineErrs

func CombineErrs(errs []error) error

CombineErrs bundles a slice of errors into a single composite error that unwraps to its members. Order is preserved and nils are skipped. Returns nil for an empty/fully-nil slice, or the sole error when there is exactly one.

func ComputeCacheKey

func ComputeCacheKey(moduleDir dt.DirPath, stagedFiles []dt.RelFilepath) string

ComputeCacheKey generates a cache key from module directory and staged files

func ErrValue

func ErrValue[T any](err error, key string) (T, bool)

ErrValue extracts a single metadata value by key with type safety. Returns the value and true if found and the value is of type T. Returns the zero value of T and false if not found or type mismatch.

Example:

status, ok := ErrValue[int](err, "http_status")
if ok {
    fmt.Printf("Status: %d\n", status)
}

name, ok := ErrValue[string](err, "parameter_name")

func Errors

func Errors(err error) []error

Errors returns the errors stored on a doterr entry. If err is a doterr entry, returns its errors. If err is a joined error (has Unwrap() []error), scans immediate children left-to-right and returns errors from the first doterr entry found. Otherwise returns nil. The returned slice preserves insertion order and is a copy.

Note: These errors may be sentinel errors (e.g., ErrRepo), custom error types (e.g., *rfc9457.Error), or any other error type stored in the entry.

func FindErr

func FindErr[T error](err error) (out T, ok bool)

FindErr walks an error tree (including errors.Join trees) and returns the first match for target (via errors.As).

func InteractiveRestage

func InteractiveRestage(ctx context.Context, groups []CommitGroup, repo *gitutils.Repo) (err error)

InteractiveRestage guides user through restaging files according to groups

func MsgErr

func MsgErr(msg any) error

MsgErr creates an ad-hoc error message without requiring a sentinel error. This is a convenience for rapid development - use sentinels for production code.

Accepts two forms:

  • MsgErr("message") - creates error with the given message
  • MsgErr(err) - wraps existing error, preserving error chain for errors.Is()

Use this when you don't want to define a sentinel immediately. Future tooling can detect MsgErr usage and suggest/generate appropriate sentinel errors.

For errors with metadata, use NewErr with a sentinel, or wrap with WithErr:

err := MsgErr("config invalid")
err = WithErr(err, "path", configPath)

func NewErr

func NewErr(parts ...any) error

NewErr builds a standalone structured entry (no primary cause inside). Accepted parts:

  • error — sentinel/tag (required: at least one, must be first)
  • KV{Key,Value} — explicit key/value
  • "key", value — implicit pair (value can be any type, including error)
  • error — optional trailing cause (joined last via errors.Join)

Pattern: one or more sentinels (error), then zero or more key-value pairs, then optional trailing cause (error). After the first string key, all remaining args must form valid pairs, except for an optional final error. Returns nil if no meaningful parts are provided after validation. Returns a validation error joined with the partial entry if validation fails.

func PersistResult

func PersistResult(result *Results, cacheKey string) (err error)

PersistResult saves analysis results to cache for later retrieval

func WithErr

func WithErr(parts ...any) error

WithErr is a flexible enrichment helper. Typical uses:

// Enrich an existing composite error (err may be an errors.Join tree):
err = WithErr(err, "Foo", 10)

// Build an entry and join a trailing cause in one shot:
err = WithErr("endpoint", ep, ErrTemplate, cause) // 'cause' is last

Behavior:

  1. If the FIRST arg is an error, it is treated as the base error to enrich: • If it is a doterr entry, merge KVs/sentinels into that entry. • If it is a multi-unwrap (errors.Join tree), find the RIGHTMOST doterr entry, merge into it, and rebuild preserving order. • If no doterr entry is found, a new entry will be joined in (see step 3).

  2. After consuming the base (if present), if the LAST remaining arg is an error, it is treated as the CAUSE and joined LAST.

  3. The remaining middle args (if any) are collected into an entry. If we enriched an existing doterr entry in step 1, that merged entry is used; otherwise, a fresh entry is created. If there is a trailing CAUSE from step 2, the result is errors.Join(entry, cause). If there is no cause, the entry is returned.

Note: For inter-function composition, prefer New() with trailing cause:

return NewErr(ErrRepo, "key", val, cause) // cause last

Types

type AnalyzeArgs

type AnalyzeArgs struct {
	ModuleDir dt.DirPath
	CacheKey  string // For persistence
}

AnalyzeArgs contains arguments for the Analyze function

type CommitGroup

type CommitGroup struct {
	Title     string
	Files     []dt.RelFilepath
	Rationale string
	Suggested bool // AI suggested vs user-defined
}

CommitGroup represents a suggested grouping of files for a single commit

func RunMultiCommitFlow

func RunMultiCommitFlow(ctx context.Context, args MultiCommitFlowArgs) (groups []CommitGroup, err error)

RunMultiCommitFlow analyzes staged changes and suggests commit groupings

func SuggestGroupings

func SuggestGroupings(ctx context.Context, args GroupingArgs) (groups []CommitGroup, err error)

SuggestGroupings asks AI to suggest logical groupings for staged changes

type ErrKV

type ErrKV interface {
	Key() string
	Value() any
}

ErrKV represents a key/value metadata pair. Keys are preserved in insertion order, and values may be of any type.

func AnyKV

func AnyKV(key string, value any) ErrKV

AnyKV creates a KV with any value type. Use this for custom types or when the specific type constructor doesn't exist.

func AppendKV

func AppendKV(kvs []ErrKV, parts ...any) []ErrKV

AppendKV appends key-value pairs to a slice of KV values. It accepts variadic arguments in three forms:

  1. Individual KV values: AppendKV(kvs, StringKV("foo", "bar"))
  2. String key-value pairs: AppendKV(kvs, "foo", "bar")
  3. Lazy ErrKV functions: AppendKV(kvs, func()ErrKV{ return StringKV("expensive", compute()) })

This function is useful for accumulating metadata throughout a function before creating an error:

var kvs []ErrKV
kvs = AppendKV(kvs, "user_id", userID)
if complexCondition {
    kvs = AppendKV(kvs, "reason", "complex")
}
return NewErr(ErrFailed, kvs, cause)

String key-value pairs must come in even counts (odd counts panic in debug mode). Lazy functions (func()ErrKV) are wrapped and not evaluated until error creation.

func BoolKV

func BoolKV(key string, value bool) ErrKV

BoolKV creates a KV with a bool value.

func ErrMeta

func ErrMeta(err error) []ErrKV

ErrMeta returns the key/value pairs stored on all doterr entries in the error tree. If err is a doterr entry, returns its metadata. If err is a joined error (has Unwrap() []error), scans all children recursively and collects metadata from all doterr entries found, preserving order. Otherwise returns nil. The returned slice preserves insertion order across all entries.

func ErrorKV

func ErrorKV(key string, value error) ErrKV

ErrorKV creates a KV with an error value. Use this when you want to include an error as metadata (not as a cause).

func Float64KV

func Float64KV(key string, value float64) ErrKV

Float64KV creates a KV with a float64 value.

func Int64KV

func Int64KV(key string, value int64) ErrKV

Int64KV creates a KV with an int64 value.

func IntKV

func IntKV(key string, value int) ErrKV

IntKV creates a KV with an int value.

func StringKV

func StringKV(key, value string) ErrKV

StringKV creates a KV with a string value.

type GroupingArgs

type GroupingArgs struct {
	StagedFiles []dt.RelFilepath
	Analysis    Results
	AIAgent     *askai.Agent
}

GroupingArgs contains arguments for commit grouping suggestions

type IsDotErrEntry

type IsDotErrEntry = interface {
	IsDotErrEntry()
	HasKV(key string, value any) bool
	MatchKV(key string, value any) bool
}

type MultiCommitFlowArgs

type MultiCommitFlowArgs struct {
	ModuleDir       dt.DirPath
	AnalysisResults *Results
	AIAgent         *askai.Agent
}

MultiCommitFlowArgs contains arguments for running the multi-commit flow

type Results

type Results struct {
	Timestamp      time.Time
	BaselineTag    string
	ModulePath     string
	OverallVerdict goutils.VerdictType

	// Individual analysis results (bespoke types from goutils)
	API   goutils.APICompatResult
	AST   goutils.ASTDiffResult
	Tests goutils.TestSignalsResult
}

Results contains all pre-commit analysis results

func Analyze

func Analyze(ctx context.Context, args AnalyzeArgs) (result Results, err error)

Analyze performs pre-commit analysis on staged changes This function demonstrates the architecture: - Direct function calls (no pluggable interface for execution) - Bespoke result handling (accessing specific fields) - Generic formatting (using AnalysisResult interface)

func AnalyzeWithCache

func AnalyzeWithCache(ctx context.Context, moduleDir dt.DirPath, cacheKey string, writer io.Writer) (results *Results, err error)

AnalyzeWithCache runs pre-commit analysis with caching support It tries to load from cache first, and if not found, runs fresh analysis

func LoadPersistedResult

func LoadPersistedResult(cacheKey string) (result *Results, err error)

LoadPersistedResult loads analysis results from cache

func (Results) FormatForAI

func (r Results) FormatForAI() string

FormatForAI generates markdown for AI prompts This demonstrates generic formatting using the AnalysisResult interface

func (Results) FormatForTerminal

func (r Results) FormatForTerminal() string

FormatForTerminal generates ANSI-escaped output for terminal display This also demonstrates generic formatting

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL