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
- func CheckKeyLimit(n int) error
- func Emit(f Filter, d Display, opts EmitOpts) (string, []string)
- func Hash(f Filter, d Display) string
- func KeyLimitMessage(n int) string
- func LooksLike(s string) bool
- func Match(it Issue, f Filter) bool
- func MatchIn(it Issue, f Filter, z calendar.Zone) bool
- func QueryURL(hash string) string
- func ResolveIdentity(res *Result, people []Person, me Identity)
- func ResolvePeople(res *Result, people []Person, me string)
- func SplitKeys(raw string) []string
- type Display
- type EmitOpts
- type Extracted
- type Filter
- type Identity
- type Issue
- type Opts
- type Person
- type Result
Constants ¶
const ( ErrEmpty = "empty" ErrNotJQL = "not_jql" ErrFilterID = "filter_id" ErrParse = "parse" ErrTooManyKeys = "too_many_keys" )
Error codes on Result.Error.
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 ¶
CheckKeyLimit returns an error when n is above MaxKeys.
func Emit ¶
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 ¶
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 ¶
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 ¶
LooksLike reports whether the paste should be tried as JQL rather than full-text. Conservative: plain words stay FTS.
func Match ¶
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
MatchIn is Match with an explicit calendar zone. Tests pin Asia/Seoul.
func ResolveIdentity ¶
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 ¶
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.
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 Extracted ¶
Extracted is the JQL (or filter id) pulled out of a paste — a raw query, a Jira navigator URL, or a `jql=` fragment.
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 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 ¶
Person is one identity ResolvePeople can match a JQL assignee/reporter value against (email, display name, account id).
func PeopleFromIssues ¶
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.