util

package
v2.1.9 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Utility functions (inspired by Kotlin) for slices.

Index

Constants

View Source
const DefaultPollInterval = 30 * time.Second
View Source
const ExampleTicketUrlPattern = "https://jira.example.com/browse/{TicketNumber}"

ExampleTicketUrlPattern is the example ticket URL pattern shown in help text, prompts, and tests.

View Source
const GhRetries = 2

Number of times to retry a "gh" command that fails due to network errors.

View Source
const IndexLockRetries = 5

Number of times to retry a "git" command that fails due to ".git/index.lock" contention.

View Source
const MatchAnyRemainingArgs = "MatchCommandWithAnyRemainingArgs"

Can be used use as last value of [TestExecutor.fakeResponses] [ExecuteResponse.Args]

View Source
const MaxUiLegendShownCount = 3

MaxUiLegendShownCount is the number of times the UI legend is shown before it auto-disables.

View Source
const RetryDelay = 1 * time.Second

Variables

View Source
var CurrentVersion string

Functions

func Execute

func Execute(options ExecuteOptions, programName string, args ...any) (string, error)

Executes a shell program with arguments.

func ExecuteOrDie

func ExecuteOrDie(options ExecuteOptions, programName string, args ...any) string

Executes a shell program with arguments. Panics if there is an error.

func ExecuteOrDieTrimmed

func ExecuteOrDieTrimmed(options ExecuteOptions, programName string, args ...any) string

Executes a shell program with arguments, trims whitespace from output, and panics if there is an error.

func FilterSlice

func FilterSlice[V any](slice []V, f func(V) bool) []V

Returns a slice containing only elements matching the given predicate.

func Fprint

func Fprint(w io.Writer, a ...any)

print or dies.

func Fprintln

func Fprintln(w io.Writer, a ...any)

println or dies.

func GetConfigFile added in v2.0.12

func GetConfigFile(filenameWithoutPath string) string

GetConfigFile returns the full path to a config file in ConfigHome if it exists, or "" if it does not.

func GetCurrentBranchName

func GetCurrentBranchName() string

Returns current branch name.

func GetRepoName

func GetRepoName() string

func IncrementLegendShownCount added in v2.1.2

func IncrementLegendShownCount(legend LegendType)

IncrementLegendShownCount increments the shown count for the given legend type in metrics.yaml.

func MapSlice

func MapSlice[V, R any](slice []V, f func(V) R) []R

Returns a slice containing the results of applying the given transform function to each element in the original array.

func RegisterTestInitHook added in v2.1.1

func RegisterTestInitHook(hook func(t *testing.T))

RegisterTestInitHook registers a function to be called during test initialization. This allows packages like interactive and gitutil to register hooks without creating import cycles. Hooks must be idempotent as they may be called multiple times per test.

func RequireGitRef added in v2.1.3

func RequireGitRef(s string)

RequireGitRef panics if s is empty or starts with a hyphen. Git interprets arguments starting with "-" as flags, so passing an unvalidated ref (branch name, commit hash) from an external source (e.g. GitHub API) could cause git to treat it as an option.

func RequireHexString added in v2.1.3

func RequireHexString(s string)

RequireHexString panics if s is not a non-empty hexadecimal string. Use this to validate git commit hashes before interpolating them into jq filters or other query strings.

func RequireHostname added in v2.1.3

func RequireHostname(s string)

RequireHostname panics if s contains characters outside the set allowed in hostnames (alphanumeric, dots, hyphens, underscores). Empty strings are allowed. Use this to validate hostnames before interpolating them into jq filters or other query strings.

func RequireNotEmptyString

func RequireNotEmptyString(s string)

func RetryGhOnNetworkError added in v2.1.9

func RetryGhOnNetworkError(executionCount int, stderr string) bool

RetryGhOnNetworkError retries gh commands on network errors and retryable HTTP errors (5xx, 408, etc.). Does not retry on 3xx or 429 (rate limit).

func RetryOnIndexLock added in v2.1.6

func RetryOnIndexLock(executionCount int, stderr string) bool

RetryOnIndexLock retries when a git command fails due to transient ".git/index.lock" contention, up to IndexLockRetries times.

func RunTestInitHooks added in v2.1.1

func RunTestInitHooks(t *testing.T)

RunTestInitHooks calls all registered test initialization hooks.

func SaveTicketUrlPattern added in v2.1.1

func SaveTicketUrlPattern(pattern string)

SaveTicketUrlPattern saves the ticketUrlPattern value to the config file, preserving any existing config values.

func SetAppConfig added in v2.0.12

func SetAppConfig(config AppConfig)

SetAppConfig sets the global AppConfig. Must be called once at startup (main or test setup).

func SetDefaultSleep

func SetDefaultSleep(newSleep func(d time.Duration))

Override the default sleep. For use by tests.

func SetGlobalExecutor

func SetGlobalExecutor(executor Executor)

Sets the executor that Execute will use.

func SetUserConfig added in v2.1.1

func SetUserConfig(config UserConfig)

SetUserConfig sets the global UserConfig. Should be called early in command execution.

func Sleep

func Sleep(d time.Duration)

Sleep function that can be overridden for testing. Default is time.Sleep

func VersionSuffix added in v2.1.4

func VersionSuffix() string

VersionSuffix returns " (stable)" or " (preview)" based on whether CurrentVersion matches stableVersion.

Types

type AppConfig

type AppConfig struct {
	Io            StdIo
	AppExecutable string         // Path of this executable.
	Exit          func(code int) // Call os.Exit with the given code, or panic during unit tests.

	DemoMode bool
	// contains filtered or unexported fields
}

Config to help with unit testing the app. For example, it allows testing code paths that would otherwise call os.Exit().

func GetAppConfig added in v2.0.12

func GetAppConfig() AppConfig

GetAppConfig returns the global AppConfig. Panics if SetAppConfig has not been called.

func NewAppConfig added in v2.1.3

func NewAppConfig(io StdIo, appExecutable string, exit func(code int), userCacheDir string, configHome string, demoMode bool) AppConfig

NewAppConfig creates a new AppConfig, ensuring the config and cache directories exist.

func (AppConfig) CacheDir added in v2.1.3

func (c AppConfig) CacheDir() string

CacheDir returns the path to the app cache directory.

func (AppConfig) ConfigHome added in v2.0.12

func (c AppConfig) ConfigHome() string

ConfigHome returns the path to the config directory.

type DefaultExecutor

type DefaultExecutor struct{}

Default implementation of Executor.

func (DefaultExecutor) Execute

func (defaultExecutor DefaultExecutor) Execute(options ExecuteOptions, programName string, args ...any) (string, error)

Implementation of Execute that uses exec.Command.

type ExecuteOptions

type ExecuteOptions struct {
	// What to use for input and output. Overriding input is useful for "git apply"
	// If output is not set then output is returned from Execute.
	// Any nil In/Err/Out values are ignored.
	Io StdIo
	// For example "MY_VAR=some_value"
	EnvironmentVariables []string
	// ShouldRetry decides whether to re-run after a failure. If nil, a default is
	// chosen based on the program name (see [defaultShouldRetry]).
	ShouldRetry ShouldRetryFunc
}

Options for [ExecuteWithOptions].

type ExecutedResponse

type ExecutedResponse struct {
	Out         string   // Out to return.
	Err         error    // error to return.
	ProgramName string   // Program name to match or that was used.
	Args        []string // Arguments that were used.
	Faked       bool     // Whether this response was faked.
}

Response that was executed or will be faked.

type Executor

type Executor interface {
	Execute(options ExecuteOptions, programName string, args ...any) (string, error)
}

Provides a simple way to execute shell commands. Allows swapping in a TestExecutor via Dependency Injection during tests.

type HistoricalData

type HistoricalData struct {
	// contains filtered or unexported fields
}

func NewHistoricalData

func NewHistoricalData(filename string, maxHistory int) HistoricalData

maxHistory Max history to store, or -1 for no max.

func (HistoricalData) AddToHistory

func (d HistoricalData) AddToHistory(newHistoryItem string)

Add a most recently used item to history.

func (HistoricalData) ReadHistory

func (d HistoricalData) ReadHistory() []string

history items are returned as: [0] least recent [last element] most recent

func (HistoricalData) SetHistory

func (d HistoricalData) SetHistory(history []string)

SetHistory replaces the entire history with the provided slice.

type LegendType added in v2.1.2

type LegendType string

LegendType identifies a specific interactive UI legend.

const (
	LegendUserSelection       LegendType = "userSelection"
	LegendTableSelection      LegendType = "tableSelection"
	LegendTableMultiselection LegendType = "tableMultiselection"
	LegendDuplicateSubject    LegendType = "duplicateSubject"
)

type MetricsConfig added in v2.1.2

type MetricsConfig struct {
	UserSelectionLegendShownCount       int `yaml:"userSelectionLegendShownCount,omitempty"`
	TableSelectionLegendShownCount      int `yaml:"tableSelectionLegendShownCount,omitempty"`
	TableMultiselectionLegendShownCount int `yaml:"tableMultiselectionLegendShownCount,omitempty"`
	DuplicateSubjectLegendShownCount    int `yaml:"duplicateSubjectLegendShownCount,omitempty"`
}

func LoadMetricsFile added in v2.1.2

func LoadMetricsFile() MetricsConfig

LoadMetricsFile reads metrics.yaml from the cache directory if it exists.

func (MetricsConfig) GetLegendShownCount added in v2.1.2

func (m MetricsConfig) GetLegendShownCount(legend LegendType) int

GetLegendShownCount returns the shown count for the given legend type.

type PrettyHandler

type PrettyHandler struct {
	slog.Handler // delegate all Handler methods to this object, except Handle which is overridden.
	// contains filtered or unexported fields
}

Handler for slog that uses different ANSI colors for each level (DEBUG, INFO, etc.).

Modified from https://betterstack.com/community/guides/logging/logging-in-go/

func NewPrettyHandler

func NewPrettyHandler(
	out io.Writer,
	opts slog.HandlerOptions,
) *PrettyHandler

Create a new PrettyHandler.

func (*PrettyHandler) Handle

func (h *PrettyHandler) Handle(ctx context.Context, r slog.Record) error

Print a log record.

func (*PrettyHandler) SetOut

func (h *PrettyHandler) SetOut(out io.Writer)

type PromptForReviewType added in v2.0.12

type PromptForReviewType string

PromptForReviewType controls whether and how the user is prompted to mark a PR as ready for review.

const (
	PromptForReviewNever   PromptForReviewType = "never"
	PromptForReviewPromptY PromptForReviewType = "promptY"
	PromptForReviewPromptN PromptForReviewType = "promptN"
)

func (PromptForReviewType) IsValid added in v2.0.12

func (t PromptForReviewType) IsValid() bool

type ShouldRetryFunc added in v2.1.6

type ShouldRetryFunc func(executionCount int, stderr string) bool

ShouldRetryFunc decides whether to re-run a command after a failure. It receives the 1-based execution count (1 = first attempt) and the command's stderr. Return true to retry.

func RetryUpTo added in v2.1.6

func RetryUpTo(maxRetries int) ShouldRetryFunc

RetryUpTo returns a ShouldRetryFunc that retries on any failure, up to maxRetries times.

type StdIo

type StdIo struct {
	Out io.Writer
	Err io.Writer
	In  io.Reader
}

Allows unit testing the use of standard i/o.

type TestExecutor

type TestExecutor struct {
	Responses []ExecutedResponse
	// contains filtered or unexported fields
}

Fake Executor for testing.

func (*TestExecutor) Execute

func (t *TestExecutor) Execute(options ExecuteOptions, programName string, args ...any) (string, error)

Checks [TestExecutor.fakeResponses] for any match before calling DefaultExecutor.Execute.

func (*TestExecutor) SetResponse

func (t *TestExecutor) SetResponse(out string, err error, fakeProgramName string, fakeArgs ...string)

Adds a response to [TestExecutor.fakeResponses]. If [fakeArgs] ends with MatchAnyRemainingArgs, then the last argument is treated as a wildcard for any remaining args. Response are checked in the reverse order that they are added (in other words, the most recent response that was added is checked first)

func (*TestExecutor) SetResponseFunc

func (t *TestExecutor) SetResponseFunc(out string, err error, isMatch func(programName string, args ...string) bool)

Adds a response to [TestExecutor.fakeResponses].

type UserConfig added in v2.0.12

type UserConfig struct {
	PromptForReview               PromptForReviewType
	PollInterval                  time.Duration
	TicketUrlPattern              string
	WorktreeMainBranchGuard       WorktreeMainBranchGuardType
	ShowWorktrees                 bool
	ShowUserSelectionLegend       bool
	ShowTableSelectionLegend      bool
	ShowTableMultiselectionLegend bool
	ShowDuplicateSubjectLegend    bool
	NoTemplate                    bool
}

UserConfig holds runtime configuration from config file and --config flag key=value entries.

func GetUserConfig added in v2.1.1

func GetUserConfig() UserConfig

GetUserConfig returns the global UserConfig. Panics if SetUserConfig has not been called.

func NewUserConfig added in v2.0.12

func NewUserConfig(fileConfig YamlConfig, flagValues map[string]string, metrics MetricsConfig) UserConfig

NewUserConfig merges hardcoded defaults, file config, and --config flag entries. metrics provides the per-legend shown counts (from metrics.yaml).

type WorktreeMainBranchGuardType added in v2.1.1

type WorktreeMainBranchGuardType string

WorktreeMainBranchGuardType controls how the main branch is determined in secondary worktrees.

const (
	WorktreeMainBranchGuardPath WorktreeMainBranchGuardType = "path"
	WorktreeMainBranchGuardNone WorktreeMainBranchGuardType = "none"
)

func (WorktreeMainBranchGuardType) IsValid added in v2.1.1

func (t WorktreeMainBranchGuardType) IsValid() bool

type WriteRecorder

type WriteRecorder struct {
	// contains filtered or unexported fields
}

An io.Writer that outputs to a string and also to Stdout. Useful for testing so that log output can still be seen in the output of the test if the test failed, and the output of the program can be asserted against. Safe for concurrent use.

func NewWriteRecorder

func NewWriteRecorder(stdout io.Writer) *WriteRecorder

Creates a new WriteRecorder that writes to Stdout.

func (*WriteRecorder) String

func (r *WriteRecorder) String() string

func (*WriteRecorder) Write

func (r *WriteRecorder) Write(p []byte) (n int, err error)

type YamlConfig added in v2.0.12

type YamlConfig struct {
	PromptForReview         PromptForReviewType         `yaml:"promptForReview,omitempty"`
	PollInterval            string                      `yaml:"pollInterval,omitempty"`
	TicketUrlPattern        string                      `yaml:"ticketUrlPattern,omitempty"`
	WorktreeMainBranchGuard WorktreeMainBranchGuardType `yaml:"worktreeMainBranchGuard,omitempty"`
	ShowWorktrees           *bool                       `yaml:"showWorktrees,omitempty"`
	ShowUiLegend            *bool                       `yaml:"showUiLegend,omitempty"`
	NoTemplate              *bool                       `yaml:"noTemplate,omitempty"`
}

func LoadUserConfigFile added in v2.0.12

func LoadUserConfigFile() YamlConfig

LoadUserConfigFile reads config.yaml from ConfigHome if it exists.

Jump to

Keyboard shortcuts

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