Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyEnvOverrides(paths Paths, cc *jira.ClientConfig) error
- func Fatal(format string, args ...any)
- func HelpFirstLine(help, fallback string) string
- func LoadConfig(paths Paths) (jira.ClientConfig, AppConfig, *ConfigFile, error)
- func LooksLikeIssueKey(s string) bool
- func MarshalConfig(cf ConfigFile) ([]byte, error)
- func NewGlobalFlagSet(jsonMode, debug, version, helpRequested *bool) *flag.FlagSet
- func Parse(env *Env, args []string, setup func(*flag.FlagSet)) (*flag.FlagSet, error)
- func PersistCloudID(paths Paths, effectiveSite, cloudID string, raw *ConfigFile)
- func PrintJSON(w io.Writer, v any) error
- func ReadTextInput(bodyFile string, tail []string, stdin io.Reader) (text string, provided bool, err error)
- func ReadTokenFile(paths Paths, tokenFile string) (string, error)
- func ResolveEnvToken(paths Paths) (string, error)
- func ResolveToken(paths Paths, cf ConfigFile) (string, error)
- func StdinIsPiped() bool
- func Usage(w io.Writer, paths Paths, d *Dispatcher)
- func ValidateSDConfig(cfg AppConfig, paths Paths) error
- type AppConfig
- type Cmd
- type CmdFlags
- type ConfigDefaults
- type ConfigFile
- type Dispatcher
- type EmitOpts
- type Env
- func (e *Env) Emit(opts EmitOpts) error
- func (e *Env) EmitJSON(opts EmitOpts) error
- func (e *Env) EmitJSONError(err error)
- func (e *Env) EmitList(items any, key string, meta map[string]any, human func()) error
- func (e *Env) EmitListOrEmpty[T any](items []T, key, resource string, render func([]T)) error
- func (e *Env) EmitMutation(action, key string, meta map[string]any, human func()) error
- func (e *Env) EmitRefreshed[T RawJSONer](ctx context.Context, action, key, humanMsg string, meta map[string]any, ...) error
- func (e *Env) EmitSkipped(key, reason string) error
- func (e *Env) Empty(msg string)
- func (e *Env) EmptyKey(key, resource string)
- func (e *Env) Notice(format string, args ...any)
- type Envelope
- type ErrKind
- type ErrorDetail
- type Fallback
- type FieldRecord
- type InputSource
- type MultiFlag
- type Pagination
- type Paths
- type RawJSONer
- type ShortcutDoc
- type ValidationError
Constants ¶
const ( ActionCreated = "created" ActionUpdated = "updated" ActionSkipped = "skipped" ActionCommented = "commented" ActionTransitioned = "transitioned" ActionLinked = "linked" ActionUnlinked = "unlinked" ActionWatched = "watched" ActionUnwatched = "unwatched" ActionAttached = "attached" ActionDownloaded = "downloaded" ActionUploaded = "uploaded" ActionLabeled = "labeled" ActionUnlabeled = "unlabeled" ActionWikiLinked = "wiki-linked" ActionWikiUnlinked = "wiki-unlinked" )
Action constants identify mutations in JSON output.
const ( SummaryTruncate = 55 // issue summary next to key + status/due columns CommentBriefTrunc = 120 // one-line comment in smart-view / `jcli comments` CommentInlineTrunc = 60 // `jcli recent` reason rows (tighter — beside date + author) LinkSummaryTrunc = 50 // printLinks summary column HistoryValueTrunc = 40 // printHistory before/after values WikiExcerptTrunc = 80 // wiki search result snippet )
Shared display truncation widths.
const DefaultBoardFilter = jira.NotDoneJQL
DefaultBoardFilter applies when defaults.board_filter is empty or absent.
const EnvelopeVersion = "2"
EnvelopeVersion identifies the JSON schema; bump it for breaking changes.
const MaxParallelFetches = 10
MaxParallelFetches limits concurrent API calls within a fetch operation.
Variables ¶
var ErrHelpShown = errors.New("help shown")
ErrHelpShown means help was printed to stderr. Return it unchanged so main exits successfully.
var ErrUnknownCommand = errors.New("unknown command")
ErrUnknownCommand means neither the command index nor Fallback matched. Dispatch has already printed usage in human mode.
Functions ¶
func ApplyEnvOverrides ¶
func ApplyEnvOverrides(paths Paths, cc *jira.ClientConfig) error
func HelpFirstLine ¶
HelpFirstLine returns the first line of help, or fallback when help is empty.
func LoadConfig ¶
func LoadConfig(paths Paths) (jira.ClientConfig, AppConfig, *ConfigFile, error)
LoadConfig reads configuration, applies environment overrides, and validates credentials. The returned raw config is nil when no file exists.
func LooksLikeIssueKey ¶
LooksLikeIssueKey reports whether s is shaped like a Jira issue key.
func MarshalConfig ¶
func MarshalConfig(cf ConfigFile) ([]byte, error)
MarshalConfig serializes cf as pretty-printed JSON with a trailing newline.
func NewGlobalFlagSet ¶
NewGlobalFlagSet defines leading global flags and discards parser output.
func Parse ¶
Parse accepts flags anywhere before "--" and enforces the dispatcher's minimum positional count. Read positionals from FlagSet.Args. setup may be nil for commands without flags. Help returns ErrHelpShown.
func PersistCloudID ¶
func PersistCloudID(paths Paths, effectiveSite, cloudID string, raw *ConfigFile)
PersistCloudID saves a discovered ID for the configured site only. It does nothing if raw is nil or already has a cloud ID.
func ReadTextInput ¶
func ReadTextInput(bodyFile string, tail []string, stdin io.Reader) (text string, provided bool, err error)
ReadTextInput reads a body file, explicit or piped stdin, or joined positional text. Files and stdin are trimmed. A file and positional text conflict; provided=false means there was no input source.
func ReadTokenFile ¶
ReadTokenFile reads and trims a token, warning if group or other permissions are set.
func ResolveEnvToken ¶
ResolveEnvToken prefers JIRA_TOKEN to JIRA_TOKEN_FILE; neither set returns ("", nil).
func ResolveToken ¶
func ResolveToken(paths Paths, cf ConfigFile) (string, error)
ResolveToken prefers the inline token to TokenFile. It returns "" if neither is set.
func StdinIsPiped ¶
func StdinIsPiped() bool
StdinIsPiped reports whether stdin is a pipe or redirected file, not a TTY.
func Usage ¶
func Usage(w io.Writer, paths Paths, d *Dispatcher)
Usage prints top-level help using the dispatcher's command list.
func ValidateSDConfig ¶
ValidateSDConfig checks the settings required by RequireSD commands.
Types ¶
type AppConfig ¶
type AppConfig struct {
SDProjects []string
BoardID string
BoardFilter string
ChecklistField string
FormsCountField string
}
AppConfig holds command settings, separate from HTTP client configuration.
func (AppConfig) ChecklistAvailable ¶
ChecklistAvailable reports whether a checklist field is configured.
func (AppConfig) ChecklistFields ¶
ChecklistFields returns "summary" plus the configured checklist field, if any.
func (AppConfig) IsSDProject ¶
IsSDProject matches the issue key's project against SDProjects, ignoring case.
type Cmd ¶
type Cmd struct {
MinArgs int // minimum positionals the handler requires
Flags CmdFlags
Desc string // one-line description for Usage listing
Help string // help text; first line is used in usage errors
// Subcommands routes a command group; when set, Run is ignored.
Subcommands *Dispatcher
Run func(ctx context.Context, env *Env, args []string) error
}
Cmd describes a subcommand. Run receives raw arguments and must call Parse to parse flags and enforce MinArgs.
type CmdFlags ¶
type CmdFlags uint8
CmdFlags declares leaf-command requirements. Zero requires a client but no SD config.
type ConfigDefaults ¶
type ConfigDefaults struct {
Board string `json:"board,omitzero"`
BoardFilter string `json:"board_filter,omitzero"`
SDProjects []string `json:"sd_projects,omitzero"`
ChecklistField string `json:"checklist_field,omitzero"`
FormsCountField string `json:"forms_count_field,omitzero"`
}
ConfigDefaults holds board and service-desk settings.
type ConfigFile ¶
type ConfigFile struct {
Site string `json:"site"`
CloudID string `json:"cloud_id,omitzero"`
Email string `json:"email"`
// Token stores an inline API token. init defaults to a separate token file.
Token string `json:"token,omitzero"`
TokenFile string `json:"token_file,omitzero"`
// Scoped selects gateway URLs and Bearer auth for a scoped API token.
Scoped bool `json:"scoped,omitzero"`
Defaults ConfigDefaults `json:"defaults,omitzero"`
}
ConfigFile is the config.json format.
func LoadConfigFile ¶
func LoadConfigFile(paths Paths) (*ConfigFile, error)
LoadConfigFile reads the on-disk configuration without opening token files. Credential precedence is resolved separately by LoadConfig.
type Dispatcher ¶
type Dispatcher struct {
Name string // for errors and usage ("jcli" or "jcli wiki")
Prefix string // Env.Command prefix ("" or "wiki ")
Index map[string]Cmd // subcommand name → spec
Shortcuts []ShortcutDoc // rendered in usage before Index
Fallback Fallback
Usage func(w io.Writer)
}
Dispatcher routes top-level or nested commands using a shared Env.
func (*Dispatcher) Dispatch ¶
Dispatch matches a command case-insensitively, connects if needed, checks requirements, and invokes its handler or nested dispatcher.
func (*Dispatcher) WriteCommandList ¶
func (d *Dispatcher) WriteCommandList(w io.Writer)
WriteCommandList writes aligned shortcuts followed by alphabetical commands.
type EmitOpts ¶
type EmitOpts struct {
Data any // payload; nil for pure mutations
Action string // "commented", "created", "skipped", ...
Key string // target resource identifier
Meta map[string]any // non-essential context
Pagination *Pagination // cursor-paginated results
Human func() // human-mode closure (writes to env.Stdout)
}
EmitOpts configures a single emission. Zero value is valid.
type Env ¶
type Env struct {
Client *jira.Client // nil until Connect runs; NoClient handlers never get one
Cfg AppConfig
Paths Paths
Stdout io.Writer
Stderr io.Writer
JSONMode bool
// Connect loads Client and Cfg when the dispatcher first needs them.
Connect func(ctx context.Context) error
// Command is the dispatched path (e.g. "wiki page"), included in JSON envelopes.
Command string
// contains filtered or unexported fields
}
Env holds per-run state and routes command output to text or JSON.
func (*Env) EmitJSON ¶
EmitJSON unconditionally writes the v2 envelope to env.Stdout. Use for commands that always emit JSON regardless of --json (schema, forms raw).
func (*Env) EmitJSONError ¶
EmitJSONError writes an error envelope, validation details, and pending warnings to Stderr. The caller sets the exit code.
func (*Env) EmitListOrEmpty ¶
EmitListOrEmpty renders non-empty lists in human mode and reports empty ones on stderr. JSON mode always emits an array, including [] for empty lists.
func (*Env) EmitMutation ¶
EmitMutation is the shorthand for a mutation with no refetched data.
func (*Env) EmitRefreshed ¶
func (e *Env) EmitRefreshed[T RawJSONer](ctx context.Context, action, key, humanMsg string, meta map[string]any, fetch func(context.Context) (T, error)) error
EmitRefreshed refetches and emits raw JSON in JSON mode. Text mode prints humanMsg only.
func (*Env) EmitSkipped ¶
EmitSkipped reports a no-op with action="skipped" and a successful exit.
type Envelope ¶
type Envelope struct {
Version string `json:"version"`
Command string `json:"command"`
Data jsontext.Value `json:"data,omitzero"`
Action string `json:"action,omitzero"`
Key string `json:"key,omitzero"`
Pagination *Pagination `json:"pagination,omitzero"`
Meta map[string]any `json:"meta,omitzero"`
Warnings []string `json:"warnings,omitzero"`
Error *ErrorDetail `json:"error,omitzero"`
}
Envelope wraps JSON command output. Error identifies failure; Data is omitted on failure and for mutations without a payload.
type ErrKind ¶
type ErrKind string
ErrKind is the envelope error taxonomy. Consumers should treat unknown values as ErrKindClient (non-retryable).
const ( ErrKindNotFound ErrKind = "not_found" ErrKindAuth ErrKind = "auth" ErrKindRateLimited ErrKind = "rate_limited" ErrKindServer ErrKind = "server" ErrKindClient ErrKind = "client" ErrKindNetwork ErrKind = "network" ErrKindValidation ErrKind = "validation" ErrKindCancelled ErrKind = "cancelled" )
type ErrorDetail ¶
type ErrorDetail struct {
Kind ErrKind `json:"kind"`
Retryable bool `json:"retryable"`
Hint string `json:"hint,omitzero"`
Message string `json:"message"`
}
ErrorDetail classifies a failure. Retryable is advisory; automatic retries have already finished when this is emitted.
func ClassifyError ¶
func ClassifyError(err error) ErrorDetail
ClassifyError checks wrapped errors, defaulting to non-retryable client errors. Validation takes precedence over HTTP errors; context and HTTP checks precede net.Error because their types can also satisfy that interface.
type Fallback ¶
Fallback rewrites an unknown command. handled=true dispatches the new arguments; false leaves the command unknown.
type FieldRecord ¶
type FieldRecord struct {
AllowedValues []string `json:"allowed_values,omitzero"`
FieldID string `json:"field_id"`
Name string `json:"name,omitzero"`
Required bool `json:"required,omitzero"`
SetExample string `json:"set_example,omitzero"`
Supplied any `json:"supplied,omitzero"`
Type string `json:"type,omitzero"`
}
FieldRecord describes a validation failure and, when available, a suggested fix.
type InputSource ¶
type InputSource int
InputSource identifies where ReadTextInput will read from.
const ( InputNone InputSource = iota InputFile // --body-file InputStdin // explicit "-" arg or piped/redirected stdin InputArgs // positional args joined with spaces )
func ClassifyInput ¶
ClassifyInput selects an input source without I/O. A file and positional text conflict.
type MultiFlag ¶
type MultiFlag []string
MultiFlag implements flag.Value for repeatable string flags (e.g. --set).
type Pagination ¶
type Pagination struct {
NextCursor string `json:"next_cursor,omitzero"`
HasMore bool `json:"has_more"`
}
Pagination carries cursor-based pagination state for list commands.
type Paths ¶
Paths holds the home and configuration directories resolved at startup.
func DefaultPaths ¶
DefaultPaths resolves Home and ConfigDir (honouring XDG_CONFIG_HOME on Linux via os.UserConfigDir). Falls back to $HOME/.config.
func (Paths) ConfigPath ¶
ConfigPath is the canonical on-disk location of jcli's config JSON.
func (Paths) ContractHome ¶
ContractHome replaces the home-directory prefix with "~".
type ShortcutDoc ¶
ShortcutDoc describes a Fallback shortcut in command help.
type ValidationError ¶
type ValidationError struct {
Err error // joined per-issue errors (errors.Join)
Hint string // short cue for ErrorDetail.Hint
MissingFields []FieldRecord // required but absent → meta.missing_fields
UnknownFields []FieldRecord // not in editmeta/createmeta → meta.unknown_fields
InvalidValues []FieldRecord // value not in allowedValues → meta.invalid_values
}
ValidationError carries local validation failures and field-specific details for JSON error metadata.
func (*ValidationError) Error ¶
func (v *ValidationError) Error() string
func (*ValidationError) Unwrap ¶
func (v *ValidationError) Unwrap() error