Documentation
¶
Overview ¶
Package cmdutil holds the cross-cutting helper layer shared by every jira-cli command: envelope writers, client/profile accessors, output-mode resolution, mutation gates, the credential-warning sink, and small generic value helpers. It is a strict leaf package — it depends on the shared internal/cli, internal/config, internal/jira, and internal/adf layers but never on cmd/jira or any internal/cli/<command> package.
Index ¶
- Constants
- func ADFModeFor(cmd *cobra.Command, mutation bool) adfmode.Mode
- func ActiveProfile(cmd *cobra.Command, cfg *config.Config) config.Profile
- func AddCacheStateFields(data map[string]any, sourceState string, count int)
- func AssigneeSummary(user *jira.User) map[string]any
- func CacheConfigPath(cmd *cobra.Command) string
- func CacheKeyForProfile(cmd *cobra.Command, profile config.Profile) string
- func CacheKeyFromStartup(globals startup.Globals, cfg *config.Config, profileName string) string
- func CacheReadOrFetch(profile, resource string, ttl time.Duration, refresh bool, ...) (json.RawMessage, bool, time.Time, string, error)
- func CacheStateForCount(sourceState string, count int) string
- func CompleteProfileNames(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective)
- func ConfigPath(cmd *cobra.Command) string
- func ConfiguredEditorFor(cmd *cobra.Command) string
- func CopyAnyMap(in map[string]any) map[string]any
- func CredentialStoreFor(backend config.SecretBackend) config.CredentialStore
- func DetectorFromContext(cmd *cobra.Command) cli.Detection
- func EnvelopeWritten(err error) error
- func ExistingProfileOrDefault(cfg *config.Config, name string) config.Profile
- func ExtendDryRunFlag(flags *pflag.FlagSet)
- func ExtendFileFlag(flags *pflag.FlagSet, name, group, placeholder string)
- func ExtendFlag(flags *pflag.FlagSet, name string, extra clib.FlagExtra)
- func ExtendForceFlag(flags *pflag.FlagSet)
- func ExtendPaginationFlags(flags *pflag.FlagSet)
- func ExtendRefreshFlags(flags *pflag.FlagSet)
- func ExtendSafetyFlag(flags *pflag.FlagSet, name string)
- func ExtendWatcherUserFlag(flags *pflag.FlagSet)
- func ExtendWatcherValidationFlags(flags *pflag.FlagSet)
- func FirstNonEmpty(values ...string) string
- func FoldRawWarningsIntoData(data any, warnings []map[string]any) any
- func FoldWarningsIntoData(data any, warnings []cli.Warning) any
- func GroupCommand(use, short, group string) *cobra.Command
- func IssueOutput(issues []*jira.Issue, detail bool) any
- func IssueService(client *jira.Client) jira.IssueService
- func IssueSummary(issue *jira.Issue) map[string]any
- func JiraClientForCommand(cmd *cobra.Command) (*jira.Client, config.Profile, bool, error)
- func JiraClientForProfile(cmd *cobra.Command, profile config.Profile) (*jira.Client, config.Profile, bool, error)
- func MarshalNonNilSlice(v any) (json.RawMessage, error)
- func MirrorADFWarningsToStderr(stderr io.Writer, warnings []cli.Warning) error
- func NewHelpRenderer() *help.Renderer
- func NoInputRequested(cmd *cobra.Command) bool
- func PlainOptionsForCommand(cmd *cobra.Command) []cli.PlainOption
- func PrimeBoards(ctx context.Context, client *jira.Client, ttlMinutes int, unbounded bool) (jira.BoardsCacheFile, []map[string]any, error)
- func ProfileForCommand(cmd *cobra.Command) (config.Profile, error)
- func ProfileForEnvelope(cmd *cobra.Command) string
- func RawWarningsToCLI(warnings []map[string]any) []cli.Warning
- func ReadJSONFile(path string, dst any) error
- func ReadOnlyEnabled(cmd *cobra.Command) bool
- func RecordCredentialWarnings(cmd *cobra.Command, warns []string)
- func RequestedProfile(cmd *cobra.Command) string
- func SearchService(client *jira.Client) jira.SearchService
- func SecretRefFor(profile config.Profile, backend config.SecretBackend) (config.SecretRef, error)
- func StandardHelpSections(cmd *cobra.Command) []help.Section
- func StringFromAny(v any) string
- func UpsertProfile(cfg *config.Config, profile config.Profile)
- func UseCompactOutput(cmd *cobra.Command) bool
- func UsePlainOutput(cmd *cobra.Command) bool
- func WireObjectString(v any, key string) string
- func WithCredentialWarnSink(ctx context.Context) context.Context
- func WithDetector(ctx context.Context, det cli.Detection) context.Context
- func WorklogService(client *jira.Client) jira.WorklogService
- func WriteEnvelope(cmd *cobra.Command, command string, data any) error
- func WriteEnvelopeWithErrors(cmd *cobra.Command, command string, data any, errorsOut []cli.Error) error
- func WriteEnvelopeWithRawWarnings(cmd *cobra.Command, command string, data any, warnings []map[string]any) error
- func WriteEnvelopeWithResponse(cmd *cobra.Command, command string, data any, resp *jira.Response) error
- func WriteEnvelopeWithResponseAndWarnings(cmd *cobra.Command, command string, data any, resp *jira.Response, ...) error
- func WriteEnvelopeWithWarnings(cmd *cobra.Command, command string, data any, warnings []adf.Warning) error
- type EnvelopeWrittenError
- type JiraServiceFactory
Constants ¶
const ( CacheStateEmpty = "empty" CacheStateFresh = "fresh" CacheStateMalformed = "malformed" CacheStateMissing = "missing" CacheStateRefresh = "refresh" CacheStateStale = "stale" )
Cache source-state labels recorded on an envelope's data.cache_source_state field, describing how a cached resource was served (or why it was refetched).
Variables ¶
This section is empty.
Functions ¶
func ADFModeFor ¶
ADFModeFor resolves the ADF strict/best-effort mode for a single mutation invocation. mutation=true selects the mutation-submit default (strict) when nothing else overrides.
func ActiveProfile ¶
ActiveProfile returns the env-overlaid profile selected by the --profile flag from cfg.
func AddCacheStateFields ¶
AddCacheStateFields writes the cache_state / cache_source_state / cache_empty trio onto an envelope's data map.
func AssigneeSummary ¶
AssigneeSummary projects a user onto the compact {account_id, display_name} shape used inside an issue summary.
func CacheConfigPath ¶
CacheConfigPath returns the config path used for cache-key identity: the root --config flag value when set, otherwise the default config path.
func CacheKeyForProfile ¶
CacheKeyForProfile returns the cache namespace key for an explicit profile, derived from the profile identity (name + base URL) and the active config path. The key names the on-disk cache directory, so its composition must stay stable — see TestCacheKeyFromStartupGolden.
func CacheKeyFromStartup ¶
CacheKeyFromStartup returns the cache namespace key for the pre-cobra startup scan, resolving the named profile against cfg when available and falling back to the bare (profile, "", configPath) identity otherwise.
func CacheReadOrFetch ¶
func CacheReadOrFetch(profile, resource string, ttl time.Duration, refresh bool, fetch func() (json.RawMessage, error)) (json.RawMessage, bool, time.Time, string, error)
CacheReadOrFetch is the read-then-fetch helper every cache subcommand uses. Returns the JSON-encoded resource bytes, whether the value was served from disk, and the state observed before any fetch.
func CacheStateForCount ¶
CacheStateForCount collapses the source state to "empty" when the resource carried no records, otherwise returns the observed state.
func CompleteProfileNames ¶
func CompleteProfileNames(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective)
CompleteProfileNames completes the names of all profiles in the config. It is shared by every command that accepts a profile argument (e.g. config and auth). On any config-load error it returns no completions rather than an error, so the shell degrades gracefully.
func ConfigPath ¶
ConfigPath returns the value of the root --config persistent flag.
func ConfiguredEditorFor ¶
ConfiguredEditorFor resolves the editor command for a command: the active profile's editor when set, otherwise the global config editor.
func CopyAnyMap ¶
CopyAnyMap returns a shallow copy of in.
func CredentialStoreFor ¶
func CredentialStoreFor(backend config.SecretBackend) config.CredentialStore
CredentialStoreFor returns the credential store implementation for a secret backend.
func DetectorFromContext ¶
DetectorFromContext returns the output-detection result installed on the command context, or the zero Detection when none is present.
func EnvelopeWritten ¶
EnvelopeWritten wraps err so a RunE can tell the central error writer it already emitted a structured error envelope.
func ExistingProfileOrDefault ¶
ExistingProfileOrDefault returns a copy of the named profile from cfg if it exists, or a new Profile with the given name. Used to merge a partial update instead of wholesale replacing the persisted profile.
func ExtendDryRunFlag ¶
ExtendDryRunFlag attaches Safety-group metadata to the --dry-run flag.
func ExtendFileFlag ¶
ExtendFileFlag marks a flag as a file-path input with the given group and placeholder label.
func ExtendFlag ¶
ExtendFlag attaches clib display metadata to the named flag in flags.
func ExtendForceFlag ¶
ExtendForceFlag attaches Safety-group metadata to the --force flag.
func ExtendPaginationFlags ¶
ExtendPaginationFlags attaches Pagination-group metadata to the --limit and --all flags.
func ExtendRefreshFlags ¶
ExtendRefreshFlags attaches Cache-group metadata to the --refresh and --ttl-minutes flags, and Pagination-group metadata to --unbounded.
func ExtendSafetyFlag ¶
ExtendSafetyFlag attaches Safety-group metadata to the named flag.
func ExtendWatcherUserFlag ¶
ExtendWatcherUserFlag attaches User-group metadata to the --user flag.
func ExtendWatcherValidationFlags ¶
ExtendWatcherValidationFlags attaches Validation-group metadata to the --no-readback and --validate-remote flags.
func FirstNonEmpty ¶
FirstNonEmpty returns the first non-empty string in values, or "".
func FoldRawWarningsIntoData ¶
FoldRawWarningsIntoData folds a raw map-shaped warning slice into a compact payload. See foldWarnings.
func FoldWarningsIntoData ¶
FoldWarningsIntoData folds a typed cli.Warning slice into a compact payload. See foldWarnings.
func GroupCommand ¶
GroupCommand returns a *cobra.Command suitable for use as a named subcommand group (no Run/RunE — only subcommands are registered on it).
func IssueOutput ¶
IssueOutput renders a list of issues for an envelope's data payload. With detail it returns the full issue records; otherwise it returns the compact per-issue summary maps. Shared by the issue list and search commands so both surface an identical compact shape.
func IssueService ¶
func IssueService(client *jira.Client) jira.IssueService
IssueService is a shorthand for ServicesForClient(client).Issue().
func IssueSummary ¶
IssueSummary projects an issue onto the stable compact field set (key, summary, status, assignee, priority, updated). Null-safe: missing fields keep their zero placeholder so the shape never varies.
func JiraClientForCommand ¶
JiraClientForCommand builds a Jira client for the env-overlaid active profile selected by the --profile flag.
func JiraClientForProfile ¶
func JiraClientForProfile(cmd *cobra.Command, profile config.Profile) (*jira.Client, config.Profile, bool, error)
JiraClientForProfile builds a Jira client targeting an explicit profile rather than the env-overlaid active profile. Read-modify-write commands that persist server data (`auth whoami --save`) use this so the live request and the saved record come from the same file-backed profile: a JIRA_PROFILE_*_BASE_URL overlay cannot redirect the request to another tenant whose identity would then be written into the file profile. Credential env sources (token/password env vars) are still honored.
func MarshalNonNilSlice ¶
func MarshalNonNilSlice(v any) (json.RawMessage, error)
MarshalNonNilSlice marshals v but rewrites nil slices to `[]` so cache files never contain `null`. Without this, decoding back into a typed slice produces nil and downstream consumers either crash or paper over the bug with `if x == nil` patches.
func MirrorADFWarningsToStderr ¶
MirrorADFWarningsToStderr is a thin wrapper around cli.RouteWarnings for the plain-mode warning-only path used by both WriteEnvelopeWithWarnings and WriteEnvelopeWithResponseAndWarnings.
func NewHelpRenderer ¶
NewHelpRenderer builds the themed clib help renderer used by every command in jira-cli. The JIRA env-prefix is set so that JIRA_NO_COLOR and related variables are honored.
func NoInputRequested ¶
NoInputRequested reports whether the caller opted out of interactive prompts via the root --no-input flag. It is the single source of truth for headless-mode detection across every subcommand.
Commands MUST read root persistent flags through this helper rather than re-declaring a same-name local flag: a local flag of the same name shadows the inherited one, so `jira --no-input issue create` would set the root flag while the handler read an unset local copy.
func PlainOptionsForCommand ¶
func PlainOptionsForCommand(cmd *cobra.Command) []cli.PlainOption
PlainOptionsForCommand builds the plain-renderer option set for a command, threading TTY detection, terminal width, and (when available) the active profile's base URL.
func PrimeBoards ¶
func PrimeBoards(ctx context.Context, client *jira.Client, ttlMinutes int, unbounded bool) (jira.BoardsCacheFile, []map[string]any, error)
PrimeBoards fetches every board (and its project keys) for the profile and returns the normalized cache file plus any warnings describing data dropped during the prime (bad records, unsafe project keys, partial pagination).
func ProfileForCommand ¶
ProfileForCommand resolves the active profile for a command WITHOUT constructing a Jira client or touching any credential backend. Local preview and dry-run paths use this so a validation-only run cannot fail on a locked keyring or an offline 1Password backend. Commands that make live HTTP calls must still go through JiraClientForCommand.
func ProfileForEnvelope ¶
ProfileForEnvelope returns the profile name to record in an envelope: the requested profile when set, otherwise the configured default profile, or "default" when neither is available.
func RawWarningsToCLI ¶
RawWarningsToCLI converts free-form map-shaped warnings into typed cli.Warning values, dropping empty entries.
func ReadJSONFile ¶
ReadJSONFile decodes exactly one JSON document from path (or stdin when path is "-") into dst. A trailing second value, stray structural byte, or syntax error is reported as a malformed-payload error.
func ReadOnlyEnabled ¶
ReadOnlyEnabled reports whether the active profile (or the JIRA_READ_ONLY env var) blocks mutations. Env wins on the OFF→ON direction so an agent shell can enforce read-only globally without editing config.
func RecordCredentialWarnings ¶
RecordCredentialWarnings appends resolution warnings to the command's sink, if one is installed. Commands without a sink (direct test calls) drop the warnings silently — they are diagnostics, not results.
func RequestedProfile ¶
RequestedProfile returns the value of the root --profile persistent flag.
func SearchService ¶
func SearchService(client *jira.Client) jira.SearchService
SearchService is a shorthand for ServicesForClient(client).Search().
func SecretRefFor ¶
SecretRefFor derives the credential identity for a profile under a given backend. The credential is keyed by the profile's Jira site host and name; an unsafe profile name is rejected here rather than producing a malformed keyring entry.
func StandardHelpSections ¶
StandardHelpSections returns the standard clib help sections for cmd, with subcommand listing made optional.
func StringFromAny ¶
StringFromAny returns v when it is a string, or "" otherwise.
func UpsertProfile ¶
UpsertProfile replaces the matching profile in cfg by name, or appends it when no profile with that name exists.
func UseCompactOutput ¶
UseCompactOutput reports whether the command runs in compact mode.
func UsePlainOutput ¶
UsePlainOutput reports whether the command runs in a plain (human) or TUI output mode.
func WireObjectString ¶
WireObjectString reads a string field out of a Jira wire object value (e.g. the "key" of a {"key":"KAN"} project object). It returns "" when the value is not an object or the field is absent / not a string.
func WithCredentialWarnSink ¶
WithCredentialWarnSink returns a context carrying a fresh credential-warning sink. PersistentPreRunE installs one per command invocation.
func WithDetector ¶
WithDetector returns a context carrying the resolved output-detection result. PersistentPreRunE installs one per command invocation; tests use it to seed a command context directly.
func WorklogService ¶
func WorklogService(client *jira.Client) jira.WorklogService
WorklogService is a shorthand for ServicesForClient(client).Worklog().
func WriteEnvelope ¶
WriteEnvelope emits the standard envelope shape for a command with no warnings.
func WriteEnvelopeWithErrors ¶
func WriteEnvelopeWithErrors(cmd *cobra.Command, command string, data any, errorsOut []cli.Error) error
WriteEnvelopeWithErrors emits an ok:false envelope while preserving a command's data payload. Use this when the command successfully gathered diagnostics but the diagnostics themselves mean the command is unhealthy (for example auth.status with an invalid profile).
func WriteEnvelopeWithRawWarnings ¶
func WriteEnvelopeWithRawWarnings(cmd *cobra.Command, command string, data any, warnings []map[string]any) error
WriteEnvelopeWithRawWarnings emits the standard envelope shape with a caller-supplied list of free-form warning maps. Necessary for warnings whose schema (cache-truncated, rate-limit-during-paginate) carries fields outside the cli.Warning struct's Type/Message/Field/Path/etc. surface — see contracts/envelope-shapes.md.
func WriteEnvelopeWithResponse ¶
func WriteEnvelopeWithResponse(cmd *cobra.Command, command string, data any, resp *jira.Response) error
WriteEnvelopeWithResponse emits the standard envelope shape with pagination derived from an HTTP response and no pipeline warnings.
func WriteEnvelopeWithResponseAndWarnings ¶
func WriteEnvelopeWithResponseAndWarnings(cmd *cobra.Command, command string, data any, resp *jira.Response, warnings []adf.Warning) error
WriteEnvelopeWithResponseAndWarnings is the warning-emitting envelope entry point for commands that BOTH have a paginated/HTTP response AND need to surface pipeline warnings (e.g., live-submit issue create / edit / comment / worklog where the pipeline has already validated and produced best-effort warnings before the API call). Mirrors WriteEnvelopeWithWarnings's TTY routing for plain mode so the data stays on stdout and warnings mirror to stderr as clog WRN lines.
func WriteEnvelopeWithWarnings ¶
func WriteEnvelopeWithWarnings(cmd *cobra.Command, command string, data any, warnings []adf.Warning) error
WriteEnvelopeWithWarnings is the warning-emitting envelope entry point — every command emitting structured warnings (typically from pipeline.RunMutation) calls this so warnings travel in the envelope under JSON mode and mirror to stderr under TTY/--plain (via the route helper).
Types ¶
type EnvelopeWrittenError ¶
type EnvelopeWrittenError struct{ Inner error }
EnvelopeWrittenError wraps an error a RunE returns to signal that it already emitted a structured error envelope, so the central error writer must not double-write. The inner error is still unwrapped for exit-code classification.
func (EnvelopeWrittenError) Error ¶
func (e EnvelopeWrittenError) Error() string
func (EnvelopeWrittenError) Unwrap ¶
func (e EnvelopeWrittenError) Unwrap() error
type JiraServiceFactory ¶
type JiraServiceFactory interface {
Issue() jira.IssueService
Search() jira.SearchService
Worklog() jira.WorklogService
Project(time.Duration) jira.ProjectService
}
JiraServiceFactory builds the typed Jira services a command needs from a single client. Centralizing construction here keeps every command's service wiring identical and gives tests one seam to reason about.
func ServicesForClient ¶
func ServicesForClient(client *jira.Client) JiraServiceFactory
ServicesForClient returns the default factory bound to client.