Created
August 5, 2020 17:31
-
-
Save KMontag42/c557d65f7aaa1f0a2c4e7b2c67018e0c to your computer and use it in GitHub Desktop.
jira tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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