Skip to content

Instantly share code, notes, and snippets.

@KMontag42
Created August 5, 2020 17:31
Show Gist options
  • Save KMontag42/c557d65f7aaa1f0a2c4e7b2c67018e0c to your computer and use it in GitHub Desktop.
Save KMontag42/c557d65f7aaa1f0a2c4e7b2c67018e0c to your computer and use it in GitHub Desktop.
jira tool
#!/usr/bin/env zsh
trap "tput rmcup" EXIT INT
local -a command project jstatus query ticket \
epic backlog grooming reload board sprint
zparseopts -D -E p:=project -project:=project \
q:=query -query:=query \
t:=ticket -ticket:=ticket \
e:=epic -epic:=epic \
b:=board -board:=board \
s:=sprint -sprint:=sprint
_fzf_labels() {
local fzf_cmd
fzf_cmd=(
fzf
--color dark,hl:33,hl+:37,fg+:235,bg+:136,fg+:254
--color info:254,prompt:37,spinner:108,pointer:235,marker:235
--layout=reverse
--prompt "Select a set of labels $ "
--no-clear
)
$fzf_cmd
}
_fzf_projects() {
local fzf_cmd
fzf_cmd=(
fzf
--color dark,hl:33,hl+:37,fg+:235,bg+:136,fg+:254
--color info:254,prompt:37,spinner:108,pointer:235,marker:235
--layout=reverse
--no-multi
--prompt "Select a project $ "
--no-clear
)
$fzf_cmd
}
_fzf_boards() {
local fzf_cmd
fzf_cmd=(
fzf
--color dark,hl:33,hl+:37,fg+:235,bg+:136,fg+:254
--color info:254,prompt:37,spinner:108,pointer:235,marker:235
--layout=reverse
--no-multi
--prompt "Select a board $ "
--no-clear
)
$fzf_cmd
}
_fzf_sprints() {
local fzf_cmd
fzf_cmd=(
fzf
--color dark,hl:33,hl+:37,fg+:235,bg+:136,fg+:254
--color info:254,prompt:37,spinner:108,pointer:235,marker:235
--layout=reverse
--no-multi
--prompt "Select a sprint $ "
--no-clear
--query="$query"
-1
)
$fzf_cmd
}
_fzf_jira() {
local -a fzf_args header
header=("Ctrl-o :: open")
fzf_args=(
fzf
--color dark,hl:33,hl+:37,fg+:235,bg+:136,fg+:254
--color info:254,prompt:37,spinner:108,pointer:235,marker:235
--preview "echo {} | cut -d : -f 1 | xargs jira view | pygmentize -l yaml -O style=native"
--preview-window right:60%:wrap
--select-1
--exit-0
--layout=reverse
--query="$query"
--ansi
--no-multi
--prompt "Select a ticket! $ "
--bind "ctrl-o:execute:echo {} | cut -d : -f 1 | xargs jira browse"
--no-clear
)
if [[ "$TERM" =~ "screen".* ]]; then
header+=("Ctrl-e :: edit")
fzf_args+=(--bind "ctrl-e:execute:echo {} | cut -d : -f 1 | xargs -I % tmux split-window -h 'jira edit %'")
fi
if [[ ! -z $backlog ]]; then
header+=("Ctrl-t :: take" "Ctrl-u :: untake")
fzf_args+=(
--bind "ctrl-t:execute:echo {} | cut -d : -f 1 | xargs jira take"
--bind "ctrl-u:execute:echo {} | cut -d : -f 1 | xargs jira take --default"
)
fi
if [[ ! -z $grooming ]]; then
header+=("Ctrl-d :: done")
fzf_args+=(
--bind "ctrl-n:execute:echo {} | cut -d : -f 1 | xargs jire done"
)
fi
if [[ ! -z $reload ]]; then
header+=("Ctrl-r :: reload")
fzf_args+=(
--bind "ctrl-r:abort+execute:$reload"
)
fi
fzf_args+=(--header ${(j. | .)header})
$fzf_args
}
_query() {
if [[ -z $project ]]; then
_get_project
fi
if [[ -z $query ]]; then
jira list -p $project -s created | _fzf_jira | cut -d : -f 1
else
jira list -p $project \
--query "summary ~ $query ORDER BY created" | _fzf_jira | cut -d : -f 1
fi
}
_mine() {
if [[ -z $project ]]; then
jira list --query "resolution = unresolved AND assignee=currentuser() ORDER BY created" | _fzf_jira | cut -d : -f 1
else
jira list --query "project = $project AND resolution = unresolved AND assignee=currentuser() ORDER BY created" | _fzf_jira | cut -d : -f 1
fi
}
_epics() {
local query_string
if [[ -z $project ]]; then
query_string="type = Epic ORDER BY created"
else
query_string="project = $project AND type = Epic ORDER BY created"
fi
jira list --query $query_string | _fzf_jira | cut -d : -f 1
}
_projects() {
jira request /rest/api/2/project -t project-list | _fzf_projects | cut -d : -f 1
}
_boards() {
jira request "/rest/agile/1.0/board?projectKeyOrId=$project" -t board-list | _fzf_boards | cut -d : -f 1
}
_sprints() {
jira request "/rest/agile/1.0/board/$board/sprint" -t sprint-list | _fzf_sprints | cut -d : -f 1
}
_get_epic() {
if [[ -z $epic ]]; then
epic=$(_epics)
else
epic=$epic[2]
fi
if [[ -z $epic ]]; then
echo 'No epic selected'
exit
fi
}
_get_ticket() {
if [[ -z $ticket ]]; then
ticket=$(_query)
else
ticket=$ticket[2]
fi
if [[ -z $ticket ]]; then
echo 'No ticket selected'
exit
fi
}
_get_my_ticket() {
if [[ -z $ticket ]]; then
ticket=$(_mine)
else
ticket=$ticket[2]
fi
if [[ -z $ticket ]]; then
echo 'No ticket selected'
exit
fi
}
_get_project() {
if [[ -z $project ]]; then
project=$(_projects)
fi
if [[ -z $project ]]; then
echo 'No project selected'
exit
fi
}
_get_board() {
if [[ -z $board ]]; then
board=$(_boards)
else
board=$board[2]
fi
if [[ -z $board ]]; then
echo 'No board selected'
exit
fi
}
_get_sprint() {
if [[ -z $sprint ]]; then
sprint=$(_sprints)
else
sprint=$sprint[2]
fi
if [[ -z $sprint ]]; then
echo 'No sprint selected'
exit
fi
}
_get_states_for_ticket() {
if [[ -z $ticket ]]; then
echo 'Cannot get transitions for missing ticket'
exit
fi
jira transitions $ticket | sed 's/^.*: \(.*\)/\1/'
}
_trans() {
jstatus=$1
_get_my_ticket
if [ -z $jstatus ]; then
# select from basic statuses
jstatus=$(_get_states_for_ticket | fzf --header "Select a status" --reverse)
fi
jira trans --noedit $jstatus $ticket
}
_check_project() {
if [ -z $project ]; then
echo 'Missing project flag, or default value'
echo 'Use -p/--project or supply J_DEFAULT_PROJECT'
exit
fi
}
query=$query[2]
command=$1
if [ -z $command ]; then
echo 'Missing command'
exit
fi
shift
if [ ! -z $project[2] ]; then
project=$project[2]
else
project=$J_DEFAULT_PROJECT
fi
case $command in
ls)
_mine
;;
mine)
_mine
;;
trans)
_trans $@
;;
transition)
_trans $@
;;
backlog)
_get_project
backlog=1
reload=(
jira list
-p $project
-S backlog
-s created
)
jira list -p $project -S backlog -s created | _fzf_jira
;;
take)
_get_ticket
jira take $ticket
;;
untake)
_get_ticket
jira take --default $ticket
;;
create)
_get_project
jira create -p $project
;;
epic)
local subcommand
subcommand=$1
case $subcommand in
ls)
_epics
;;
create)
_get_project
jira epic create -p $project
;;
add)
if [[ -z $epic && -z $ticket ]]; then
_get_project
fi
_get_epic && _get_ticket
jira epic add $epic $ticket
;;
remove)
if [[ -z $epic && -z $ticket ]]; then
_get_project
fi
_get_epic && _get_ticket
jira epic remove $epic $ticket
;;
tickets)
if [[ -z $epic ]]; then
_get_project
fi
_get_epic
jira epic list $epic
;;
esac
;;
help)
help_commands=(
help
ls
mine
backlog
trans
edit
take
untake
create
epic
grooming
)
help_flags=(
-t Ticket
-p Project
-q Finder Query
-e Epic
)
echo 'available commands:'
echo $help_commands[@]
echo 'available flags:'
echo $help_flags[@]
;;
grooming)
# this is like backlog, but it adds a query for no story points :)
_get_project
grooming=1
reload=(
j
grooming
)
if [[ ! -z $project ]]; then
reload+=(
-p $project
)
fi
jira list --query "project = $project AND status = Backlog AND 'Story Points' is EMPTY AND type != Epic ORDER BY created" | _fzf_jira
;;
labels)
local subcommand
subcommand=$1
shift
local label
label=$1
if [[ -z $subcommand ]]; then
echo 'Missing subcommand'
exit
fi
if [[ -z $label ]]; then
labels=(
"Icebox"
)
label=$(echo ${(j.\n.)labels} | _fzf_labels)
fi
case $subcommand in
"set")
_get_ticket
jira labels set $ticket $label
;;
remove)
_get_ticket
jira labels remove $ticket $label
;;
add)
_get_ticket
jira labels add $ticket $label
;;
esac
;;
show)
_get_ticket
jira view $ticket | pygmentize -l yaml -O "style=native" | bat
;;
view)
_get_ticket
jira view $ticket | pygmentize -l yaml -O "style=native" | bat
;;
boards)
_get_project
_get_board
;;
sprint)
local subcommand
subcommand=$1
if [[ -z $subcommand ]]; then
echo 'Missing subcommand'
exit
fi
_get_project
_get_board
case $subcommand in
active)
query="active"
_get_sprint
query=""
jira request "/rest/agile/1.0/board/$board/sprint/$sprint/issue" -t list | _fzf_jira
;;
issues)
_get_sprint
jira request "/rest/agile/1.0/board/$board/sprint/$sprint/issue" -t list | _fzf_jira
;;
esac
;;
*)
_get_ticket
jira $command $ticket
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment