jql

package
v0.18.1 Latest Latest
Warning

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

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

Documentation

Overview

Package jql translates a documented JQL subset to and from gadak's in-memory filter (the same shape the web UI serializes into the URL).

It is not a JQL engine. Clauses the subset cannot express — WAS, CHANGED, sprint by name, closedSprints(), cross-field OR, !=, saved filter ids — are listed on the result and never applied. Silence is the failure mode this package exists to prevent. Numeric `sprint =` / `sprint in` and `sprint in openSprints()` are in the subset (GDK-518).

The store stays source-neutral: this package does not import it, does not write SQL, and does not talk to Jira.

Index

Constants

View Source
const (
	ErrEmpty       = "empty"
	ErrNotJQL      = "not_jql"
	ErrFilterID    = "filter_id"
	ErrParse       = "parse"
	ErrTooManyKeys = "too_many_keys"
)

Error codes on Result.Error.

View Source
const MaxKeys = 500

MaxKeys is the compile and --keys ceiling. Above this, Parse and the CLI return a loud error that includes the count.

Variables

This section is empty.

Functions

func CheckKeyLimit

func CheckKeyLimit(n int) error

CheckKeyLimit returns an error when n is above MaxKeys.

func Emit

func Emit(f Filter, d Display, opts EmitOpts) (string, []string)

Emit writes the Jira-facing JQL for a Filter. gadak-only flags are listed in the second return (reopened, stale, …) so a round-trip cannot pretend they survived.

func Hash

func Hash(f Filter, d Display) string

Hash is the gadak UI view query string (no leading #/?). It matches web/src/lib/view-config.ts configToParams: same short keys, same omit-defaults rule. The SPA parseConfig of these params is the view.

func KeyLimitMessage

func KeyLimitMessage(n int) string

KeyLimitMessage is the compile / --keys error text. It always includes the actual count so a 501-key paste is diagnosable without a second run.

func LooksLike

func LooksLike(s string) bool

LooksLike reports whether the paste should be tried as JQL rather than full-text. Conservative: plain words stay FTS.

func Match

func Match(it Issue, f Filter) bool

Match reports whether an issue satisfies the Filter. Semantics match the web UI: AND across fields, OR within a field. Instants use the process local calendar (same default as the web owner).

func MatchIn added in v0.16.0

func MatchIn(it Issue, f Filter, z calendar.Zone) bool

MatchIn is Match with an explicit calendar zone. Tests pin Asia/Seoul.

func QueryURL

func QueryURL(hash string) string

QueryURL is the fragment a gadak window applies to an already-encoded Hash().

func ResolveIdentity

func ResolveIdentity(res *Result, people []Person, me Identity)

ResolveIdentity is the identity owner: currentUser() becomes AccountID when set, otherwise Email; roster lookups return AccountID when the matched person has one. Email-less roster rows are not skipped.

func ResolvePeople

func ResolvePeople(res *Result, people []Person, me string)

ResolvePeople replaces assignee/reporter display names and account ids with the matched person's account id (email fallback). Unresolved values move to Unsupported rather than silently matching nothing. currentUser() becomes me, which this wrapper treats as an email.

Prefer ResolveIdentity when the configured account id is known.

func SplitKeys

func SplitKeys(raw string) []string

SplitKeys splits a --keys payload on commas or any unicode space, then uppercases, trims, drops empties, and de-dupes while keeping first-seen order.

Types

type Display

type Display struct {
	Sort    string `json:"sort,omitempty"`     // updated | created | priority
	Dir     string `json:"dir,omitempty"`      // asc | desc
	GroupBy string `json:"group_by,omitempty"` // status_category is the default
}

Display is the ORDER BY / grouping fragment. Empty sort/dir means "leave the view as-is" on parse; Hash omits gadak defaults.

type EmitOpts

type EmitOpts struct {
	Email     string
	AccountID string
}

EmitOpts controls how identity is written back (currentUser vs email/id).

type Extracted

type Extracted struct {
	JQL      string
	FilterID string
	IsURL    bool
}

Extracted is the JQL (or filter id) pulled out of a paste — a raw query, a Jira navigator URL, or a `jql=` fragment.

func Extract

func Extract(input string) Extracted

Extract pulls JQL out of a navigator URL or returns the string as-is. A URL that only carries filter=<id> sets FilterID and leaves JQL empty — the id is not in the mirror.

type Filter

type Filter struct {
	StatusCategory    []string            `json:"status_category"`
	StatusCategoryNot []string            `json:"status_category_not"`
	Status            []string            `json:"status"`
	StatusNot         []string            `json:"status_not"`
	AssigneeEmail     []string            `json:"assignee_email"`
	AssigneeEmailNot  []string            `json:"assignee_email_not"`
	ReporterEmail     []string            `json:"reporter_email"`
	ReporterEmailNot  []string            `json:"reporter_email_not"`
	TeamGroup         []string            `json:"team_group"`
	TeamGroupNot      []string            `json:"team_group_not"`
	Labels            []string            `json:"labels"`
	LabelsNot         []string            `json:"labels_not"`
	Priority          []string            `json:"priority"`
	PriorityNot       []string            `json:"priority_not"`
	Severity          []string            `json:"severity"`
	SeverityNot       []string            `json:"severity_not"`
	IssueType         []string            `json:"issue_type"`
	IssueTypeNot      []string            `json:"issue_type_not"`
	Components        []string            `json:"components"`
	ComponentsNot     []string            `json:"components_not"`
	FixVersions       []string            `json:"fix_versions"`
	FixVersionsNot    []string            `json:"fix_versions_not"`
	QARun             []string            `json:"qa_run"`
	QARunNot          []string            `json:"qa_run_not"`
	QASuite           []string            `json:"qa_suite"`
	QASuiteNot        []string            `json:"qa_suite_not"`
	QAImpact          []string            `json:"qa_impact"`
	QAImpactNot       []string            `json:"qa_impact_not"`
	DeployState       []string            `json:"deploy_state"`
	DeployStateNot    []string            `json:"deploy_state_not"`
	JiraProject       []string            `json:"jira_project"`
	SourceProject     []string            `json:"source_project"`
	JiraProjectNot    []string            `json:"jira_project_not"`
	SourceProjectNot  []string            `json:"source_project_not"`
	Keys              []string            `json:"keys"`
	Parent            []string            `json:"parent"`
	SprintIDs         []string            `json:"sprint_ids"`
	SprintState       []string            `json:"sprint_state"`
	Fields            map[string][]string `json:"fields"`
	Reopened          bool                `json:"reopened"`
	Unassigned        bool                `json:"unassigned"`
	Stale             bool                `json:"stale"`
	CreatedFrom       *string             `json:"created_from"`
	CreatedTo         *string             `json:"created_to"`
	UpdatedFrom       *string             `json:"updated_from"`
	UpdatedTo         *string             `json:"updated_to"`
	DueFrom           *string             `json:"due_from"`
	DueTo             *string             `json:"due_to"`
	ResolvedFrom      *string             `json:"resolved_from"`
	ResolvedTo        *string             `json:"resolved_to"`
	Q                 string              `json:"q"`
}

Filter is the JSON shape of web/src/lib/view-config.ts ViewFilters. Empty slices marshal as [] so a client can apply the object wholesale.

func EmptyFilter

func EmptyFilter() Filter

EmptyFilter returns a Filter whose slices are non-nil, ready to marshal.

type Identity

type Identity struct {
	Email     string
	AccountID string
}

Identity is the configured Jira user ResolvePeople substitutes for currentUser().

type Issue

type Issue struct {
	Key            string
	ParentKey      string
	Project        string
	Status         string
	StatusCategory string
	Type           string
	Priority       string
	Assignee       string
	AssigneeEmail  string
	AssigneeID     string
	Reporter       string
	ReporterEmail  string
	ReporterID     string
	Labels         []string
	Components     []string
	FixVersions    []string
	CreatedAt      string
	UpdatedAt      string
	Duedate        string
	ResolvedAt     string
	SprintID       string
	SprintState    string
}

Issue is the source-neutral row Match compares to a Filter. Callers map their own lite type onto this; the package does not import store.

type Opts

type Opts struct {
	Now       time.Time
	Email     string // currentUser() fallback when AccountID is empty
	AccountID string // currentUser() body when set
}

Opts control parse-time evaluation (dates, currentUser).

type Person

type Person struct {
	Email       string
	Name        string
	DisplayName string
	AccountID   string
}

Person is one identity ResolvePeople can match a JQL assignee/reporter value against (email, display name, account id).

func PeopleFromIssues

func PeopleFromIssues(issues []Issue) []Person

PeopleFromIssues builds the resolver roster from mirrored issues.

type Result

type Result struct {
	Input       string   `json:"input,omitempty"`
	JQL         string   `json:"jql"`
	Filters     Filter   `json:"filters"`
	Display     Display  `json:"display"`
	Applied     []string `json:"applied"`
	Unsupported []string `json:"unsupported"`
	Omitted     []string `json:"omitted,omitempty"`
	Error       string   `json:"error,omitempty"`
	Message     string   `json:"message,omitempty"`
}

Result is one parse (or emit) outcome. Error is a stable code; Message is human. Unsupported clauses were understood and refused; they are never silently dropped.

func Parse

func Parse(input string, opts Opts) Result

Parse turns a JQL string or a Jira navigator URL into a Filter. Unsupported clauses are listed; they are not applied.

Jump to

Keyboard shortcuts

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