In addition to the orgOf
JQL function, OrgJQL also provides to other functions you can customize:
We'll go through both of these functions in this video.
https://youtu.be/o3aUDhD-bC8
Background
OrgJQL was written in Forthic, a language developed at LinkedIn to build hundreds of internal Jira-based tools for program and engineering management. Forthic is also the language that allows fx.users
and fx.issues
to be customized on-the-fly, directly within your Jira instance without any external servers.
Forthic in Jira
The editor for customizing OrgJQL functions is actually a Forthic IDE. You can execute words directly within the IDE and see their effect in the developer pane at the bottom of the editor:
You can define new words using this pattern:
Code Block |
---|
: NEW-WORD WORDS TO BE EXECUTED; |
For instance, we can extract 3 +
from the previous example and create a new ADD-3
definition and use it like this:
Example: Customize fx.users
Getting all the users that roll up into a manager
Let’s start by showing how to get all the users in a manager’s org. This is actually how the orgOf
JQL function is implemented.
NOTE: This assumes you have some org data set up. See “Managing Org Data” for more info.
The FULL-ORG
word returns all of the users that roll up into a manger (see the right sidebar for more info). For instance, executing the following line will return all of the users in Kai Bentley’s org:
Code Block |
---|
"Kai Bentley" FULL-ORG |
A silly example to get all users whose names are more than 12 characters
This is an example that does something that you can’t do directly in JQL. It’s a silly example, but it illustrates a useful pattern. We’ll use SELECT
to filter a list of names given a predicate, in this case, all names greater than 12 characters:
Code Block |
---|
"William MacLane" FULL-ORG "LENGTH 12 >" SELECT |
We could use this in JQL by defining a new word called MACLANE-LONG
:
Code Block |
---|
: MACLANE-LONG "William MacLane" FULL-ORG "LENGTH 12 >" SELECT; |
We can then save the code and then test the expansion in the “Test Custom JQL Functions” tab:
Get the direct reports for a manager
We can use the DIRECTS
word to get the direct reports for a manager. For instance, we could use this definition to get the direct reports for “William MacLane”:
Code Block |
---|
: MACLANE-DIRECTS "William MacLane" DIRECTS; |
In the case of DIRECTS
, we could actually just call it directly (since we can pass data to words through Forthic):
Customizing fx.issues
We’ll implement a classic JQL function that returns all Epics that have unresolved Stories. We can do this in 10 lines of Forthic:
Code Block |
---|
["project"] VARIABLES
: FIELDS ["Summary" "Parent"];
: project-EPIC-JQL ["project = " project @ " and resolved = NULL and issuetype='Epic'"] CONCAT;
: project-EPICS project-EPIC-JQL FIELDS jira.SEARCH;
: project-EPIC-KEYS-STR project-EPICS "'key' REC@" MAP UNIQUE "," JOIN;
: project-STORY-JQL ["Parent in (" project-EPIC-KEYS-STR ") and issuetype='Story' and resolved = null"] CONCAT;
: project-UNRESOLVED-STORIES project-STORY-JQL FIELDS jira.SEARCH;
: project-EPICS-w/UNRESOLVED project-UNRESOLVED-STORIES "'Parent' REC@" MAP UNIQUE SORT;
: INCOMPLETE-EPICS (project !) project-EPICS-w/UNRESOLVED; |
(Don’t worry about the syntax just yet – we’ll go over each line)
Giving it a try
The word that gives us the incomplete epics is called…INCOMPLETE-EPICS
. We can run it like this:
Code Block |
---|
"ENG" INCOMPLETE-EPICS |
Passing a parameter to a definition
If we look at the INCOMPLETE-EPICS
definition, we see that the first part of it looks like this: (project !)
. In Forthic, parentheses are whitespace, so you can ignore those. We use parentheses to indicate that we’re going to take the top of the stack and store it in a variable. The project
variable is defined in Line 1.
The !
word sets the value of a variable to what’s just before it. So, this line sets the value of project
to "ENG"
:
Code Block |
---|
"ENG" (project !) |
Naming convention: prefix definitions with variable names
When a definition uses the value of a variable, we prefix its name with the variable’s name. You can see that in Lines 4 through 9 above. Each of those words relies on the value of project
being set. Once it is, any of those can be called at will. The project
variable establishes a context that those words run in.
Line 3: FIELDS
The FIELDS
word simply defines an array of Jira fields to pull for each issue.
NOTE: Forthic arrays start with [
and consist of all objects on the stack up until ]
. Because we use the state of the stack rather than syntax to define arrays, commas are not needed to separate array elements.
Line 4: project-EPIC-JQL
The project-EPIC-JQL
word constructs the JQL to pull all the epics for a project
by concatenating strings together (the @
word retrieves the value of a variable).
This is what it looks like when project
has the value of "ENG"
:
Line 5: project-EPICS
The project-EPICS
word uses the jira.SEARCH
word from the Forthic Jira module to pull issues. This word expects a JQL string and an array of Jira fields. Here are the results when it’s run:
Line 6: project-EPIC-KEYS-STR
The project-EPIC-KEYS-STR
word extracts the issue keys for each of the epics. It uses the following to do this:
Code Block |
---|
"'key' REC@" MAP |
The MAP
word maps a Forthic string over each of the epics, retrieving the result for each item into a new array. For this case, the string "'key' REC@"
retrieves the key for each epic. The effect is to convert a list of epic records into a list of their associated issue keys. Here is the result of this word:
Line 7: project-STORY-JQL
The project-STORY-JQL
word constructs JQL to pull all of the unresolved stories for the specified epics. It is similar to the project-EPIC-JQL
word, but instead of a project, it concatenates the epic key string that we just computed into a JQL string:
This JQL string pulls all of the unresolved stories that are part of the epics of project
Line 8: project-UNRESOLVED-STORIES
The project-UNRESOLVED-STORIES
word just pulls unresolved stories using the JQL from Line 7
and the fields from Line 3
. Here’s the result from running this:
Line 9: project-EPICS-w/UNRESOLVED
The project-EPICS-w/UNRESOLVED
word just gathers the Parent
field (the Epics) from each of the unresolved stories. It uniques and sorts them. These are the incomplete epics for the project in question.
Closing Thoughts
Forthic brings new capabilities to Jira. You can essentially develop applications directly within a Jira instance instead of having to go through a long build and deploy cycle. We’ve only touched on what Forthic can do. To learn more, please sign up for Forthic Office Hours or ask us a question at the Forthix JSM portal.