blob: 751edb6054975252b61172537580a78e61badf77 [file] [log] [blame]
Joey Armstrong3134bfd2024-02-10 20:51:25 -05001#!/bin/bash
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -04002# -------------------------------------------------------------------------
Joey Armstrongcc24b3c2024-03-22 11:12:23 -04003# Copyright 2023-2024 Open Networking Foundation Contributors
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http:#www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# -----------------------------------------------------------------------
17# SPDX-FileCopyrightText: 2023-2024 Open Networking Foundation Contributors
18# SPDX-License-Identifier: Apache-2.0
Joey Armstrong3134bfd2024-02-10 20:51:25 -050019## --------------------------------------------------------------------
20## Intent: Construct a jira ticket query with attributes
21## --------------------------------------------------------------------
22
Joey Armstrong76f861a2024-03-13 16:01:24 -040023{ # loader
24 declare pgm=''
25 pgm="$(realpath --canonicalize-existing "$0")"
26
Joey Armstrongcc24b3c2024-03-22 11:12:23 -040027 # stack-trace-on-error
28 # interrupt handler
29 # mkdir with auto-cleanup at exit
Joey Armstrong76f861a2024-03-13 16:01:24 -040030 declare root=''
31 root="${pgm%%/jira/bin/jira-search.sh}"
32 source "$root/lf/onf-common/common.sh" '--common-args-begin--'
33
34 pgm_lib="${root}/jira/jira-search"
35 readonly pgm_lib
36
37 pgm_bin="${root}/bin"
38 readonly pgm_bin
Joey Armstrongcc24b3c2024-03-22 11:12:23 -040039
40 pgm_help="${root}/jira/jira-search/help"
41 readonly pgm_help
Joey Armstrong76f861a2024-03-13 16:01:24 -040042}
43
Joey Armstrong3134bfd2024-02-10 20:51:25 -050044# set -euo pipefail
45#source ~/.sandbox/trainlab-common/common.sh '--common-args-begin--'
46
47##-------------------##
48##---] GLOBALS [---##
49##-------------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -040050declare -g -a is_empty=() # label
51
Joey Armstrong3134bfd2024-02-10 20:51:25 -050052declare -g -a text=()
53declare -g -a text_and=()
54declare -g -a text_or=()
55
56declare -g -a urls_raw=()
57declare -g -a urls_filt=()
58
59declare -g -a labels_incl=()
60declare -g -a labels_excl=()
61
62declare -g -a projects=()
63
64path="$(realpath $0 --canonicalize-existing)"
Joey Armstrong76f861a2024-03-13 16:01:24 -040065source "${pgm_lib}/utils.sh"
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -040066source "${pgm_lib}/include.sh"
Joey Armstrong76f861a2024-03-13 16:01:24 -040067source "${pgm_lib}/fixversion.sh"
68source "${pgm_lib}/resolved.sh"
Joey Armstrongcc24b3c2024-03-22 11:12:23 -040069source "${pgm_lib}/help/utils.sh"
Joey Armstrong3134bfd2024-02-10 20:51:25 -050070
71## --------------------------------------------------------------------
72## --------------------------------------------------------------------
73function error()
74{
Joey Armstrongc5542fa2024-03-25 11:49:47 -040075 cat <<ERROR
76
77** -----------------------------------------------------------------------
78** IAM: ${FUNCNAME[1]}
79** ERROR: $@
80** -----------------------------------------------------------------------
81ERROR
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -040082 echo
Joey Armstrong3134bfd2024-02-10 20:51:25 -050083 exit 1
84}
85
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -040086## --------------------------------------------------------------------
87## --------------------------------------------------------------------
88function banner()
89{
90 cat <<MSG
91
92** -----------------------------------------------------------------------
93** $@
94** -----------------------------------------------------------------------
95MSG
96 return
97}
98
99## -----------------------------------------------------------------------
100## Intent: Append a conditional token in the list based on context
101## -----------------------------------------------------------------------
102function and_or()
103{
104 local -n ref=$1; shift
105 local val="$1" ; shift
106
107 if [[ ${#ref[@]} -gt 0 ]]; then
108 if [[ -v bool_or ]]; then
109 ref+=('OR')
110 else
111 ref+=('AND')
112 fi
113 fi
114
115 ref+=("$val")
116 return
117}
118
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500119## -----------------------------------------------------------------------
120## -----------------------------------------------------------------------
121function html_encode()
122{
123 local -n ref=$1; shift
124 local tmp="$ref"
125
126 tmp="${tmp//[[:space:]]/%20}"
127 tmp="${tmp//\"/%22}"
128 tmp="${tmp//\'/%27}"
129
130 ref="$tmp"
131 return
132}
133
134## -----------------------------------------------------------------------
135## Intent: Insert a conjunction into the stream when prior statements exist
136## -----------------------------------------------------------------------
137function conjunction()
138{
139 return
Joey Armstrong76f861a2024-03-13 16:01:24 -0400140
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500141 local -n ref=$1; shift
142 [[ $# -gt 0 ]] && { local literal="$1"; shift; }
143
144 ## -------------------------------
145 ## Conjunction if prior statements
146 ## -------------------------------
147 if [ ${#ref[@]} -gt 0 ]; then
148 if [[ -v literal ]]; then
149 ref+=("$literal")
150 elif [[ -v bool_and ]]; then
151 ref+=('AND')
152 else
153 ref+=('OR')
154 fi
155 fi
156
157 return
158}
159
160## -----------------------------------------------------------------------
161## Intent: Helper method
162## -----------------------------------------------------------------------
163## Usage : local path="$(join_by '/' 'lib' "${fields[@]}")"
164## -----------------------------------------------------------------------
165function join_by()
166{
167 local d=${1-} f=${2-}; if shift 2; then printf %s "$f" "${@/#/$d}"; fi;
168}
169
170## --------------------------------------------------------------------
171## Intent: Query by component name filter
172## --------------------------------------------------------------------
173## Value: helm-charts
174## --------------------------------------------------------------------
175function do_components()
176{
177 declare -n args=$1; shift
178 declare -n ans=$1; shift
179
180 # [ -z ${args+word} ] && { args=(); }
Joey Armstrong76f861a2024-03-13 16:01:24 -0400181
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500182 if [[ ${#args[@]} -gt 0 ]]; then
183
184 local modifier
185 if [[ -v bool_not ]]; then
186 modifier='NOT IN'
187 else
188 modifier='IN'
189 fi
190 ans+=("component ${modifier} (${args[@]})")
191 # alt: comp='foo' OR comp='bar'
192 fi
193
194 return
195}
196
197## --------------------------------------------------------------------
198## Intent: Query filter by labels assigned to a ticket:
199## o pods, failing, testing
200## --------------------------------------------------------------------
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400201## Perform a few string joins
202## - elements {in,not-in} label {excl, incl}
203## - OR: is-empty + in-label
204## - AND: excl + incl
205## --------------------------------------------------------------------
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500206# "project in (UKSCR, COMPRG) AND issuetype = Bug AND labels in (BAT)" and
207## --------------------------------------------------------------------
208function do_labels()
209{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400210 local -n incl=$1; shift # was args=
211 local -n excl=$1; shift
212 local -n ans=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500213
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400214 ## -------------------------------
215 ## Join #1: is-empty + labels-incl
216 ## -------------------------------
217 local -a tokens=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500218
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400219 if [[ " ${is_empty[*]} " =~ ' label ' ]]; then
220 tokens+=('(labels IS EMPTY)')
221 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500222
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400223 ## ------------------------------
224 ## Construct label include filter
225 ## ------------------------------
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500226 if [[ ${#incl[@]} -gt 0 ]]; then
227
228 local modifier
229 if [[ -v bool_not ]]; then
230 modifier='NOT IN'
231 else
232 modifier='IN'
233 fi
234
235 local labels=$(join_by ',' "${incl[@]}")
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400236 tokens+=("(labels ${modifier} ($labels))")
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500237 fi
238
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400239 # ------------------------------
240 # JOIN[OR]: is-empty + in-labels
241 # ------------------------------
242 if [[ ${#tokens[@]} -gt 1 ]]; then
243 local combine
244 combine=("$(join_by ' OR ' "${tokens[@]}")")
245 tokens=("$combine")
246 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500247
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400248 ## ------------------------------
249 ## Construct label exclude filter
250 ## ------------------------------
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500251 if [[ ${#excl[@]} -gt 0 ]]; then
252 local labels=$(join_by ',' "${excl[@]}")
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400253 tokens+=("(labels NOT IN ($labels))")
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500254 fi
255
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400256 # ------------------------------------
257 # JOIN[AND]: labels-excl + labels-incl
258 # ------------------------------------
259 if [[ ${#tokens[@]} -gt 1 ]]; then
260 tokens=("$(join_by ' AND ' "${tokens[@]}")")
261 fi
262
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500263 ans+=("${tokens[@]}")
264 return
265}
266
267## --------------------------------------------------------------------
268## Intent: Modify search query by project type (SEBA, VOL)
269## --------------------------------------------------------------------
270function do_projects()
271{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400272 local -n ref=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500273
274 [[ ${#projects[@]} -eq 0 ]] && { return; }
275
276 local terms="$(join_by ',' "${projects[@]}")"
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400277 # local -a buffer=('(' 'project' 'IN' "($terms)" ')')
278 # ref+=("$(join_by '%20' "${buffer[@]}")")
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500279 ref+=("(project IN ($terms))")
280 return
281}
282
283## --------------------------------------------------------------------
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400284## Intent: Construct query using text field filters
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500285## --------------------------------------------------------------------
286function do_text()
287{
288 local -n ref=$1; shift
289 local -n ans=$1; shift
290 local val
291
292 ## Accumulate
293 if [[ ${#ref[@]} -gt 0 ]]; then
294
295 if [[ -v bool_and ]]; then
296 text_and+=("${ref[@]}")
297 else
298 text_or+=("${ref[@]}")
299 fi
300 fi
301
302 ## Append terms: AND
303 if [[ ${#text_and[@]} -gt 0 ]]; then
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400304 local -a term=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500305 for val in "${text_and[@]}";
306 do
307 term+=("text ~ \"$val\"")
308 done
309 val=$(join_by ' AND ' "${term[@]}")
310 ans+=("($val)")
311 fi
312
313 ## Append terms: OR
314 if [[ ${#text_or[@]} -gt 0 ]]; then
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400315 local -a term=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500316 for val in "${text_or[@]}";
317 do
318 term+=("text ~ \"$val\"")
319 done
320 val=$(join_by ' OR ' "${term[@]}")
321 ans+=("($val)")
322 fi
323
324 return
325}
326
327## --------------------------------------------------------------------
328## Intent: Query by assigned or requestor
329## --------------------------------------------------------------------
330## Note: Simple for now but support query by a list of suers
331## --------------------------------------------------------------------
332function do_user()
333{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400334 local -n ans=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500335
336 [[ -v argv_nobody ]] && return
337
338 local user='currentUser()'
339 if [[ -v argv_user ]]; then
340 user="$argv_user"
341 fi
342
343 if [[ -v argv_assigned ]]; then
344 ans+=("assignee=${user}")
345 fi
346
347 if [[ -v argv_reported ]]; then
348 ans+=("reporter=${user}")
349 fi
350
351 return
352}
353
354## --------------------------------------------------------------------
355## Intent: Combine filter arguments into a search query
356## --------------------------------------------------------------------
357function gen_filter()
358{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400359 local -n ans=$1 ; shift
360 local -n args=$1 ; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500361
362 ## -----------------------------------
363 ## Begin by joining major search terms
364 ## -----------------------------------
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400365 local -a _tmp=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500366 local val
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400367
368 local -i is_paren=0
369 local -a buffer=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500370 for val in "${args[@]}";
371 do
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400372 case "$val" in
373 '(') _tmp+=("$val"); continue ;;
374 ')') _tmp+=("$val"); continue ;;
375 esac
376
377 and_or _tmp "$val"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500378 done
Joey Armstrong76f861a2024-03-13 16:01:24 -0400379
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400380 ## ----------------------------------------------------------------
381 # This was used to remove AND term when a non-query or non-argument
382 # query was needed. Any lingering logic dependent on it ?
383 ## ----------------------------------------------------------------
384 # if [[ ${#_tmp[@]} -gt 0 ]]; then
385 # unset _tmp[-1]
386 # fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500387
388 ## -----------------------
389 ## Massage with html codes
390 ## -----------------------
391 ans="$(join_by '%20' "${_tmp[@]}")"
392 return
393}
394
395## --------------------------------------------------------------------
396## Intent: Combine filter arguments into a search query
397## --------------------------------------------------------------------
398function gen_url()
399{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400400 local -n ans=$1; shift
401 local -n args=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500402
403 ## Which jira server to query (?)
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400404 [[ ! -v server ]] && local -g server='jira.opennetworking.org'
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500405 tmp_url="https://${server}/issues/?jql="
406 tmp="${tmp_url}${args}"
407 ans="${tmp// /%20}"
408 return
409}
410
411## --------------------------------------------------------------------
412## Intent: Dispaly command usage
413## --------------------------------------------------------------------
414function usage()
415{
416 cat <<EOH
417Usage: $0 VOL-xxxx
418 --debug Enable script debug mode
419 --dry-run Simulate
Joey Armstrong76f861a2024-03-13 16:01:24 -0400420 --todo Display future enhancements
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500421
422 VOL-{xxxx} View a jira ticket by ID
423
424[SERVER]
Joey Armstrong76f861a2024-03-13 16:01:24 -0400425 --server {cord,onf}
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400426 --onf jira.opennetworking.org
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500427 --opencord jira.opencord.org
428
429[WHAT]
430 --component Search by component name assigned to ticket
431 --label Search by label name assigned to ticket.
432 --text Search string(s)
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400433EOH
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500434
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400435 # local -a topics=()
436 # topics+=('fixversion.switches')
437 # topics+=('resolved.switches')
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400438 #
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400439 # help_switch_show "${topics[@]}"#
440 #
441 #[USER(s)]
442 # --me Tickets assigned to or reported by me.
443 # --user [u] Tickets assigned to this user.
444 # --nobody Raw query, no filtering by user
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500445
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500446
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400447 cat <<EOH
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500448
449[BOOL]
450 --and Join terms using 'AND'
451 --or Join terms using 'OR'
452
453[MEMBER]
454 --in (default) Items belong (--component IN)
455 --not-in Negate item set (--component NOT IN)
456
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400457[Contains] (join modifer: --and, --or, --is-empty)
458 --text [t]
459 --text-and [t] All list items
460 --text-or [t] Any list items
461 --label [l] Match label field based on modifier criteria
462 --text-and [t] All list items
463 --text-or [t] Any list items
464
465[MODIFIERS]
466 --and Combine query terms using AND keyword
467 --or Combine query terms using OR keyword
468 --in Include ticket field if list item(s) match
469 --not Negate a query
470 --is-empty Include ticket if field is empty
471 --resolved-is-empty
472 --unresolved Query for open/unresolved jira tickets.
473
474[FILTER]
475 --excl Exclude tickets whose fields match this string (filter-out)
476 --incl Include tickets whose fields match this string
477
478[--resolved]
479 --resolved-is-empty
480 --resolved-start Query by date range
481 --resolved-end Query by date range
482 --resolved(-not)-empty Query for (closed)/open tickets
483 --resolved-excl Types to exclude
484 --resolved-incl Types to include
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500485
486[RANGE]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400487 --newer [d] Search for tickets created < [n] days ago.
488 --older [d] Search for tickets created > [n] days ago.
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500489
490[ALIASES]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400491 --all Query for all unresolved tickets
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400492 --unresolved Alias for --resolved-is-empty
493 --wip Alias for --resolved-is-empty
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400494
495[TOPIC]
496 --fixversion Query by field: fixedversion
497 --resolved Query by field: resolved
498 --user Query by owner, requestor or 'my' jira tickets.
499
500[HELP]
501 --help This message
502 --help-{topic} Display switch help and use case. (--help-resolved)
503 --usage-{topic} Display use cases for a given switch (--usage-user)
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500504
505[USAGE]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400506 $0 --opencord --assigned --unresolved
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500507 o Display all tickets assigned to my login
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400508
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500509 $0 --reported --or --text 'bbsim' --text 'release'
510 o Search for tickets that contain strings bbsim or release
511 $0 --cord --text-and 'release' --text-and 'voltctl'
512 o Search jira.opencord for tickets that contain release and voltctl
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500513
514 $0 --cord --label failing --label pod
515 o Search jira.opencord for tests failing due to pod/hardware issuses.
516
517 $0 --proj VOL --fixversion "VOLTHA v2.12" --resolved-is-empty
518 o Query for unresolved release tickets
519EOH
520
521 return
522}
523
524## --------------------------------------------------------------------
525# classpath=$(join_by ':' "${mypath[@]}")
526## --------------------------------------------------------------------
527function join_by()
528{
529 local d=${1-} f=${2-}; if shift 2; then printf %s "$f" "${@/#/$d}"; fi;
530}
531
532##----------------##
533##---] MAIN [---##
534##----------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400535declare -a suffix0=() # accumulated terms to join
536declare server='jira.opencord.org'
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500537
538# declare -g -i debug=1
539
540while [ $# -gt 0 ]; do
541
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400542# if [ ${#suffix0[@]} -gt 0 ]; then
543# suffix0+=('AND')
544# fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500545
546 arg="$1"; shift
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400547 banner "ARG=[$arg], \$@=[$@]"
548
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500549 [[ -v debug ]] && echo "** argv=[$arg] [$*]"
550
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400551 getopt_detect_modifiers "$arg"
552
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500553 case "$arg" in
554
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400555 '--help') usage; exit 0 ;;
556 '--help-'*) help_with "${arg/--help-/}" ;;
557 '--usage-'*) help_usage_show "${arg/--usage-/}" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500558
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400559 '--'*'-is-empty')
560 declare -a args=()
561 args+=('--is-empty')
562
563 arg="${arg:2}" # remove prefix --
564 arg="${arg%-is-empty}" # remove suffix token-name
565 args+=("$arg")
566 [[ $# -gt 0 ]] && { args+=("$@"); }
567
568 set -- "${args[@]}"
569 ;;
570
571 '--is-empty')
572 declare val="$1"; shift
573 declare -a valid=()
574 valid+=('label')
575
576 if [[ " ${valid[@]} " =~ " ${val} " ]]; then
577 is_empty+=("$val")
578 else
579 error "Detected invalid --is-empty switch [$arg]"
580 fi
581 ;;
582
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500583 ##-----------------##
584 ##---] MODES [---##
585 ##-----------------##
586 -*debug) declare -g -i debug=1 ;;
587 --dry-run) declare -g -i dry_run=1 ;;
588
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400589 ##------------------------##
590 ##---] SWITCH ALIAS [---##
591 ##------------------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400592 --unresolved|--wip)
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400593 declare -a args=()
594 args+=('--resolved-is-empty')
595 [[ $# -gt 0 ]] && { args+=("$@"); }
596 set -- "${args[@]}"
597 ;;
598
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500599 ##-------------------##
600 ##---] BY USER [---##
601 ##-------------------##
602 --assigned) declare -g -i argv_assigned=1 ;;
603 --reported) declare -g -i argv_reported=1 ;;
604 --me) declare -g -i argv_me=1 ;;
605 --nobody) declare -g -i argv_nobody=1 ;;
606 --user)
607 arg="$1"; shift
608 declare -g argv_user="$arg"
609 ;;
610
611 ##------------------##
612 ##---] SERVER [---##
613 ##------------------##
Joey Armstrong76f861a2024-03-13 16:01:24 -0400614 --serv*)
615 arg="$1"; shift
616 case "$arg" in
617 *cord*) server='jira.opencord.org' ;;
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400618 *onf*) server='jira.opennetworking.org' ;;
619 *) error "--server [$arg] expected opencord or onf" ;;
Joey Armstrong76f861a2024-03-13 16:01:24 -0400620 esac
621 ;;
622
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400623 --onf) declare server='jira.opennetworking.org' ;;
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400624 --opencord) declare server='jira.opencord.org' ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500625
626 ##---------------------##
627 ##---] SEARCH-BY [---##
628 ##---------------------##
629 --component|--comp*)
630 arg="$1"; shift
631 [[ ! -v components ]] && declare -g -a components=()
632 components+=("$arg")
633 ;;
634
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400635 '--label-is-empty') is_empty+=('label') ;;
636
637 '--label'|'--lab'*)
638 val="$1"; shift
639 if [[ -v getopt_argv_EXCL ]]; then
640 labels_excl+=("$val")
641 elif [[ -v getopt_argv_INCL ]]; then
642 labels_incl+=("$val")
643 else
644 labels_incl+=("$val")
645 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500646 ;;
647
648 ##-----------------------##
649 ##---] Text Search [---##
650 ##-----------------------##
651 # jsearch.sh --text-and bbsim --text-and release
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400652 '--tex'*)
653 [[ $# -gt 0 ]] && { val="$1"; }
654 case "$arg" in
655 '--text-and') text_and+=("$val") ;;
656 '--text-or') text_or+=("$val") ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500657
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400658 # % js --and --text jenkins --text cord
659 # text ~ "Jira Software" # [WORDs]
660 # text ~ "\"Jira Software\"" # [STRING]
661 '--text')
662 if [[ ! -v bool_and_or ]]; then
663 error "Qualify [$arg] using --text-{and,or}"
664 elif [[ bool_and_or -eq 1 ]]; then
665 text_and+=("$1"); shift
666 elif [[ bool_and_or -eq 0 ]]; then
667 text_or+=("$1"); shift
668 else
669 error "Qualify [$arg] using --text-{and,or}"
670 fi
671 ;;
672 *) error "Qualify [$arg] using --text-{and,or}" ;;
673 esac
674 shift # $val
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500675 ;;
676
677 --all) set -- '--resolved-is-none' "$@" ;; # alias: --[un-]resolved
Joey Armstrong76f861a2024-03-13 16:01:24 -0400678 --todo) source "${pgm_lib}/todo.sh" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500679
680 --proj*) projects+=("$1"); shift ;;
681
682 --fixversion-*)
683 # function get_jql_fixversion()
684 case "$arg" in
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400685 *excl)
686 [[ ! -v fixversion_excl ]] && { declare -g -a fixversion_excl=(); }
687 val="\"$1\""; shift
688 html_encode val
689 fixversion_excl+=("$val");
690 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500691
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400692 *incl)
693 [[ ! -v fixversion_incl ]] && { declare -g -a fixversion_incl=(); }
694 val="\"$1\""; shift
695 html_encode val
696 fixversion_incl+=("$val");
697 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500698
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400699 *not-empty) declare -g -i fixversion_not_empty=1 ;;
700 *is-empty) declare -g -i fixversion_is_empty=1 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500701
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400702 *) error "Detected invalid --fixversion-* modifier" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500703 esac
704 ;;
705
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400706 '--resolved-'*)
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500707 # function get_jql_reasons()
708 case "$arg" in
709
710 *start) declare -g resolved_start="$1"; shift ;;
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400711 *end) declare -g resolved_end="$1"; shift ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500712
713 *not-empty) declare -g resolved_not_empty="$1" ;;
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400714 *empty) declare -g resolved_is_empty="$1" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500715
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400716 *excl)
717 [[ ! -v resolved_excl ]] && { declare -g -a resolved_excl=(); }
718 val="\"$1\""; shift
719 html_encode val
720 resolved_excl+=("$val");
721 ;;
722 *incl)
723 [[ ! -v resolved_incl ]] && { declare -g -a resolved_incl=(); }
724 val="\"$1\""; shift
725 html_encode val
726 resolved_incl+=("$val");
727 ;;
728 *) ;;
729 *) error "Detected invalid --resolved-* modifier" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500730 esac
731 ;;
732
733 -*newer)
734 arg="$1"; shift
735 suffix0+=("created <= '-${arg}d'") ;;
736
737 -*older)
738 arg="$1"; shift
739 suffix0+=("created >= '-${arg}d'") ;;
740
741 ##----------------##
742 ##---] BOOL [---##
743 ##----------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400744 --[aA][nN][dD])
745 declare -g -i bool_and=1
746 declare -g -i bool_and_or=1 # ! -v else toggle
747 ;;
748 --[oO][rR])
749 declare -g -i bool_or=1
750 declare -g -i bool_and_or=0
751 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500752
753 ##------------------##
754 ##---] MEMBER [---##
755 ##------------------##
756 --[iI][nN]) declare -g -i bool_in=1 ;;
757 --[nN][oO][tT]) declare -g -i bool_not=1 ;;
758
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400759 [A-Z][A-Z][A-Z]-[0-9]*) # VOL-xxxx (jira ticket)
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500760 case "$arg" in
761 CORD-[0-9]*)
762 url="https://jira.opencord.org/browse/${arg}"
763 urls_raw+=('--new-window' "$url")
764 ;;
765
766 INF-[0-9]*)
767 url="https://jira.opennetworking.org/browse/${arg}"
768 urls_raw+=('--new-window' "$url")
769 ;;
770
771 VOL-[0-9]*)
772 url="https://jira.opencord.org/browse/${arg}"
773 urls_raw+=('--new-window' "$url")
774 ;;
775
776 *) error "Detected invalid ticket [$arg]" ;;
777
778 esac
779 ;;
780
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400781 ## ---------------------------
782 ## Search all fields for value
783 ## ---------------------------
784 [[:word:]]*)
785
786 echo "MATCHED: [$arg] (LINENO: $LINENO)"
787 declare -a args=()
788 args+=('--OR')
789 args+=('--component' "$arg")
790 args+=('--label-incl' "$arg")
791 args+=('--text-or' "$arg")
792 [[ $# -gt 0 ]] && { args+=("$@"); }
793 set -- "${args[@]}"
794 ;;
795
796 -*) error "Detected unknown switch [$arg]" ;;
797
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500798 # -----------------------------------------------------------------------
799 # https://support.atlassian.com/jira-software-cloud/docs/search-syntax-for-text-fields/
800 # -----------------------------------------------------------------------
801 # +jira atlassian -- must contain jira, atlassian is optional
802 # -japan -- exclude term
803 # [STEM] summary ~ "customize" -- finds stem 'custom' in the Summary field
804 *)
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400805 echo "MATCHED: [$arg] (LINENO: $LINENO)"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500806 declare -p text_and
807 error "Detected unknown argument $arg"
808 ;;
809 esac
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400810
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500811done
812
Joey Armstrong76f861a2024-03-13 16:01:24 -0400813## --------------
814## Required check
815## --------------
816[[ ! -v server ]] && { error "--server={cord,onf} is required"; }
817
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500818## ----------------------
819## Construct query filter
820## ----------------------
821do_user suffix0
822do_projects suffix0
823[[ -v components ]] && { do_components components suffix0; }
824do_labels labels_incl labels_excl suffix0
825do_text text suffix0
826do_resolved suffix0
827do_fixversion suffix0
828
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400829declare -p suffix0
830
831if [[ -v getopt_argv_AND ]]; then
832 query="$(join_by 'AND' "${suffix0[0]}")"
833elif [[ -v getopt_argv_OR ]]; then
834 query="$(join_by 'OR' "${suffix0[0]}")"
835else
836 error "Ambiguous query [argv needs: --and or --or]"
837fi
838
839# banner "$(declare -p query)"
840
841
842
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500843filter=''
844gen_filter filter suffix0
845
846if [[ ! -v urls_raw ]]; then
847 url=''
848 gen_url url filter
849 urls_filt+=("$url")
850elif [ ${#urls_raw} -eq 0 ]; then
851 url=''
852 gen_url url filter
853 urls_filt+=("$url")
854fi
855
856[[ -v debug ]] && [[ -v url ]] && echo "URL: $url"
Joey Armstronge4ef06a2024-03-22 11:43:54 -0400857browser="${BROWSER:-firefox}"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500858echo "$browser ${urls_filt[@]} ${urls_raw[@]}"
859
860if [[ ! -v dry_run ]]; then
861 "$browser" "${urls_filt[@]}" "${urls_raw[@]}" >/dev/null 2>/dev/null &
862fi
863
864# [SEE ALSO]
865# o https://support.atlassian.com/jira-software-cloud/docs/advanced-search-reference-jql-fields/
866
867# [EOF]