cli

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package cli provides shared command-line interface utilities for wherehouse commands.

This package contains reusable helpers for CLI command implementations including:

  • Database connection management (OpenDatabase)
  • Output formatting with lipgloss styling (OutputWriter)
  • User identity resolution (GetActorUserID)
  • Flag handling utilities (IsQuietMode)

Index

Constants

This section is empty.

Variables

View Source
var ErrDatabaseNotInitialized = errors.New("database not initialized")

ErrDatabaseNotInitialized is returned when the database file does not exist on disk. Callers can use errors.Is to detect this case programmatically.

Functions

func AddItems

func AddItems(ctx context.Context, items []string, location string) error

AddItems adds a items to the database.

func CheckDatabaseExists

func CheckDatabaseExists(dbPath string) error

CheckDatabaseExists returns ErrDatabaseNotInitialized if the file at dbPath does not exist. Returns nil if the file is present. Returns a wrapped os error for any other stat failure (permissions, etc.).

func FormatRelativeTime

func FormatRelativeTime(t time.Time) string

FormatRelativeTime formats a timestamp as a human-readable relative time string.

func GetActorUserID

func GetActorUserID(ctx context.Context) string

GetActorUserID determines the actor user ID from context and config. Falls back to OS username if no config is available.

The function checks the following sources in order:

  1. Configured default identity (cfg.User.DefaultIdentity)
  2. Username mapping (cfg.User.OSUsernameMap[osUsername])
  3. OS username (fallback)

Returns the resolved actor user ID string.

func GetConfig

func GetConfig(ctx context.Context) (*config.Config, bool)

GetConfig retrieves the Config from the context. Returns the config and true if found, or nil and false if not present.

func IsQuietMode

func IsQuietMode(cmd *cobra.Command) bool

IsQuietMode checks if quiet mode is enabled. Returns true if the quiet flag count is greater than 0. Quiet levels:

  • 0: Normal output (default)
  • 1: Minimal output (-q)
  • 2+: Silent output (-qq or more)

func LocationCompletions

func LocationCompletions(ctx context.Context) ([]string, cobra.ShellCompDirective)

LocationCompletions returns the full canonical paths of all non-system locations for use as shell completions. It opens its own database connection via OpenDatabase(ctx) so that it can be called from cobra RegisterFlagCompletionFunc handlers, which run before RunE and outside the command's normal DB lifecycle.

On success it returns (paths, ShellCompDirectiveNoFileComp). On any error it returns (nil, ShellCompDirectiveError) so that the shell silently offers no completions rather than printing an error.

func LooksLikeID

func LooksLikeID(s string) bool

LooksLikeID checks if a string looks like a nanoid. Returns true if the string is exactly nanoid.IDLength characters from nanoid.Alphabet.

func MigrateDatabase

func MigrateDatabase(cmd *cobra.Command, db *database.Database, dryRun bool) error

MigrateDatabase rewrites all entity IDs from UUID format to nanoid format. It uses cmd for output (cmd.OutOrStdout()) and respects the dryRun flag. All changes are applied in a single atomic transaction; on failure no changes persist. Idempotent: if an ID already looks like a nanoid (10-char alphanumeric), it is left unchanged.

func MustGetConfig

func MustGetConfig(ctx context.Context) *config.Config

MustGetConfig retrieves the Config from the context or panics if not found. Use this when the config is guaranteed to be present (e.g., after PersistentPreRunE).

func OpenDatabase

func OpenDatabase(ctx context.Context) (*database.Database, error)

OpenDatabase opens the database connection using config settings. It extracts the database path from the context config and opens a connection with auto-migration enabled.

Returns an error if:

  • Configuration is not found in context
  • Database path cannot be resolved
  • Database file does not exist (use `wherehouse initialize database` to create it)
  • Database connection fails

func ResolveItemSelector

func ResolveItemSelector(
	ctx context.Context,
	db LocationItemQuerier,
	selector string,
	commandName string,
) (string, error)

ResolveItemSelector resolves an item selector to an item ID. Supports three selector types:

  1. ID (exact ID, verified against database)
  2. LOCATION:ITEM (both canonical names, filters by location)
  3. Canonical name (must match exactly 1 item)

The commandName parameter is used in error messages to provide context (e.g., "wherehouse move", "wherehouse history").

Returns the item ID string or error if not found or ambiguous.

func ResolveLocation

func ResolveLocation(ctx context.Context, db LocationItemQuerier, input string) (string, error)

ResolveLocation resolves a location by ID or canonical name. IDs are verified against the database before being returned. Supports both nanoid string format and display/canonical names.

Resolution order:

  1. Try direct ID lookup in the database
  2. If not found by ID, try canonical name lookup

Returns the location ID string or error if not found.

Types

type AddLocationResult

type AddLocationResult struct {
	LocationID      string
	DisplayName     string
	FullPathDisplay string // empty if fetch failed post-creation
}

AddLocationResult holds the outcome of a single location creation.

func AddLocations

func AddLocations(ctx context.Context, names []string, parentName string) ([]AddLocationResult, error)

AddLocations creates one or more named locations in the database. If parentName is non-empty, all locations are created as children of that parent. parentName may be a canonical name or ID; it is resolved via ResolveLocation. Fails fast on the first error (validation, uniqueness, or event insertion).

type FoundItemResult

type FoundItemResult struct {
	ItemID        string
	DisplayName   string
	FoundAt       string
	HomeLocation  string
	Returned      bool
	FoundEventID  int64
	ReturnEventID *int64
	Warnings      []string
}

FoundItemResult holds the outcome of marking an item as found.

func FoundItem

func FoundItem(
	ctx context.Context,
	db foundDB,
	itemID, foundLocationID string,
	returnToHome bool,
	actorUserID, note string,
) (*FoundItemResult, error)

FoundItem marks an item as found at the specified location. It fires an item.found event and, when returnToHome is true, optionally fires a follow-up item.moved rehome event to return the item to its home location.

itemID and foundLocationID must be pre-resolved IDs (not names or selectors). Use ResolveItemSelector and ResolveLocation to resolve them before calling this function.

Validates current item state before creating events. Non-fatal state mismatches (e.g. item not currently at Missing) are reported as Warnings in the result.

type LoanItemOptions

type LoanItemOptions struct {
	// Borrower is the name of the person/entity borrowing the item. Required.
	Borrower string
	// Note is an optional free-text note attached to the event.
	Note string
}

LoanItemOptions configures optional behavior for LoanItem.

type LoanItemResult

type LoanItemResult struct {
	ItemID           string
	DisplayName      string
	LoanedTo         string
	EventID          int64
	WasReLoaned      bool
	PreviousLoanedTo string
	PreviousLocation string
}

LoanItemResult holds the outcome of a single item loan operation.

func LoanItem

func LoanItem(
	ctx context.Context,
	db loanDB,
	itemSelector string,
	actorUserID string,
	opts LoanItemOptions,
) (*LoanItemResult, error)

LoanItem records an item as loaned to a borrower. Validates item state before creating the ItemLoaned event. The itemSelector may be an ID, a LOCATION:ITEM selector, or a canonical name. actorUserID is the user performing the action.

type LocationItemQuerier

type LocationItemQuerier interface {
	GetLocation(ctx context.Context, locationID string) (*database.Location, error)
	GetLocationByCanonicalName(ctx context.Context, canonicalName string) (*database.Location, error)
	GetItem(ctx context.Context, itemID string) (*database.Item, error)
	GetItemsByCanonicalName(ctx context.Context, canonicalName string) ([]*database.Item, error)
}

LocationItemQuerier is the database query interface required by resolver functions. *database.Database satisfies this interface.

type LostItemOptions

type LostItemOptions struct {
	// Note is an optional free-text note attached to the event.
	Note string
}

LostItemOptions configures optional behavior for LostItem.

type LostItemResult

type LostItemResult struct {
	ItemID           string
	DisplayName      string
	PreviousLocation string
	EventID          int64
}

LostItemResult holds the outcome of marking an item as lost.

func LostItem

func LostItem(
	ctx context.Context,
	db lostDB,
	itemSelector string,
	actorUserID string,
	opts LostItemOptions,
) (*LostItemResult, error)

LostItem marks an item as lost (moved to the system Missing location). Validates item state (must not already be missing) before creating the ItemMissing event. The itemSelector may be an ID, a LOCATION:ITEM selector, or a canonical name. actorUserID is the user performing the action.

type OutputStyles

type OutputStyles struct {
	Success lipgloss.Style
	Error   lipgloss.Style
	Warning lipgloss.Style
	Info    lipgloss.Style
	Key     lipgloss.Style
	Value   lipgloss.Style
}

OutputStyles contains lipgloss styles for consistent terminal formatting.

type OutputWriter

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

OutputWriter handles formatted output with styling support. It respects JSON mode and quiet mode flags for consistent output behavior.

func NewOutputWriter

func NewOutputWriter(out, err io.Writer, jsonMode, quietMode bool) *OutputWriter

NewOutputWriter creates an output writer with default lipgloss styles.

Parameters:

  • out: Standard output writer (typically cmd.OutOrStdout())
  • err: Error output writer (typically cmd.ErrOrStderr())
  • jsonMode: If true, output is formatted as JSON
  • quietMode: If true, suppress non-essential output

func NewOutputWriterFromConfig

func NewOutputWriterFromConfig(out, err io.Writer, cfg *config.Config) *OutputWriter

NewOutputWriterFromConfig creates an output writer using settings from a Config. Delegates to NewOutputWriter with cfg.IsJSON() and cfg.IsQuiet().

func (*OutputWriter) Error

func (w *OutputWriter) Error(msg string)

Error prints an error message to stderr. Always shown (ignores quiet mode). In JSON mode, outputs {"status":"error","message":"..."}.

func (*OutputWriter) Info

func (w *OutputWriter) Info(msg string)

Info prints an informational message to stdout. Suppressed in quiet mode. Not shown in JSON mode.

func (*OutputWriter) JSON

func (w *OutputWriter) JSON(data any) error

JSON prints arbitrary JSON data to stdout. Always outputs JSON regardless of mode flags.

func (*OutputWriter) KeyValue

func (w *OutputWriter) KeyValue(key, value string)

KeyValue prints a key-value pair with styled formatting. Suppressed in quiet mode. In JSON mode, outputs {key:value}.

func (*OutputWriter) Print

func (w *OutputWriter) Print(msg string)

Print prints plain text to stdout without styling or newline. Bypasses quiet mode (always prints). Use for scripting-friendly output.

func (*OutputWriter) Println

func (w *OutputWriter) Println(msg string)

Println prints plain text to stdout without styling, with newline. Bypasses quiet mode (always prints). Use for scripting-friendly output.

func (*OutputWriter) Success

func (w *OutputWriter) Success(msg string)

Success prints a success message to stdout. Suppressed in quiet mode. In JSON mode, outputs {"status":"success","message":"..."}.

func (*OutputWriter) Warning

func (w *OutputWriter) Warning(msg string)

Warning prints a warning message to stderr. Suppressed in quiet mode. In JSON mode, outputs {"status":"warning","message":"..."}.

func (*OutputWriter) Writer

func (w *OutputWriter) Writer() io.Writer

Writer returns the underlying io.Writer used for standard output. This allows callers to funnel output through the same writer that OutputWriter controls.

Jump to

Keyboard shortcuts

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