blob: 4710b751b142aea033eaed4ddce004ce265ef17b [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 Armstrongf8c78f02024-08-28 17:00:29 -0400334 local -n ref=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500335
336 [[ -v argv_nobody ]] && return
337
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400338 local -a buffer=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500339 local user='currentUser()'
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400340 [[ ! -v argv_users ]] && { declare -a argv_users=('currentUser()'); }
341
342 local users
343 users="$(join_by ',' "${argv_users[@]}")"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500344
345 if [[ -v argv_assigned ]]; then
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400346 if [[ ${#argv_users[@]} -eq 1 ]]; then
347 buffer+=("assignee=${user}")
348 else
349 buffer+=("(asignee in ($users))")
350 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500351 fi
352
353 if [[ -v argv_reported ]]; then
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400354 if [[ ${#argv_users[@]} -eq 1 ]]; then
355 buffer+=("reporter=${user}")
356 else
357 buffer+=("(reporter in ($users))")
358 fi
359 fi
360
361 ## --------------------------
362 ## Construct resolved queries
363 ## --------------------------
364 local query="$(join_by ' OR ' "${buffer[@]}")"
365
366 ## ----------------------------------------
367 ## Normalize parens for the composite query
368 ## ----------------------------------------
369 if [[ ${#ref[@]} -eq 0 ]]; then
370 ref+=("$query")
371 else
372 local buffer
373 buffer="$(join_by ' AND ' "(${ref[@]})" "($query)")"
374 ref=("$buffer")
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500375 fi
376
377 return
378}
379
380## --------------------------------------------------------------------
381## Intent: Combine filter arguments into a search query
382## --------------------------------------------------------------------
383function gen_filter()
384{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400385 local -n ans=$1 ; shift
386 local -n args=$1 ; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500387
388 ## -----------------------------------
389 ## Begin by joining major search terms
390 ## -----------------------------------
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400391 local -a _tmp=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500392 local val
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400393
394 local -i is_paren=0
395 local -a buffer=()
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500396 for val in "${args[@]}";
397 do
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400398 case "$val" in
399 '(') _tmp+=("$val"); continue ;;
400 ')') _tmp+=("$val"); continue ;;
401 esac
402
403 and_or _tmp "$val"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500404 done
Joey Armstrong76f861a2024-03-13 16:01:24 -0400405
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400406 ## ----------------------------------------------------------------
407 # This was used to remove AND term when a non-query or non-argument
408 # query was needed. Any lingering logic dependent on it ?
409 ## ----------------------------------------------------------------
410 # if [[ ${#_tmp[@]} -gt 0 ]]; then
411 # unset _tmp[-1]
412 # fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500413
414 ## -----------------------
415 ## Massage with html codes
416 ## -----------------------
417 ans="$(join_by '%20' "${_tmp[@]}")"
418 return
419}
420
421## --------------------------------------------------------------------
422## Intent: Combine filter arguments into a search query
423## --------------------------------------------------------------------
424function gen_url()
425{
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400426 local -n ans=$1; shift
427 local -n args=$1; shift
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500428
429 ## Which jira server to query (?)
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400430 [[ ! -v server ]] && local -g server='jira.opennetworking.org'
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500431 tmp_url="https://${server}/issues/?jql="
432 tmp="${tmp_url}${args}"
433 ans="${tmp// /%20}"
434 return
435}
436
437## --------------------------------------------------------------------
438## Intent: Dispaly command usage
439## --------------------------------------------------------------------
440function usage()
441{
442 cat <<EOH
443Usage: $0 VOL-xxxx
444 --debug Enable script debug mode
445 --dry-run Simulate
Joey Armstrong76f861a2024-03-13 16:01:24 -0400446 --todo Display future enhancements
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500447
448 VOL-{xxxx} View a jira ticket by ID
449
450[SERVER]
Joey Armstrong76f861a2024-03-13 16:01:24 -0400451 --server {cord,onf}
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400452 --onf jira.opennetworking.org
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500453 --opencord jira.opencord.org
454
455[WHAT]
456 --component Search by component name assigned to ticket
457 --label Search by label name assigned to ticket.
458 --text Search string(s)
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400459EOH
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500460
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400461 # local -a topics=()
462 # topics+=('fixversion.switches')
463 # topics+=('resolved.switches')
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400464 #
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400465 # help_switch_show "${topics[@]}"#
466 #
467 #[USER(s)]
468 # --me Tickets assigned to or reported by me.
469 # --user [u] Tickets assigned to this user.
470 # --nobody Raw query, no filtering by user
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500471
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500472
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400473 cat <<EOH
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500474
475[BOOL]
476 --and Join terms using 'AND'
477 --or Join terms using 'OR'
478
479[MEMBER]
480 --in (default) Items belong (--component IN)
481 --not-in Negate item set (--component NOT IN)
482
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400483[Contains] (join modifer: --and, --or, --is-empty)
484 --text [t]
485 --text-and [t] All list items
486 --text-or [t] Any list items
487 --label [l] Match label field based on modifier criteria
488 --text-and [t] All list items
489 --text-or [t] Any list items
490
491[MODIFIERS]
492 --and Combine query terms using AND keyword
493 --or Combine query terms using OR keyword
494 --in Include ticket field if list item(s) match
495 --not Negate a query
496 --is-empty Include ticket if field is empty
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400497 --unresolved Query for open/unresolved jira tickets.
498
499[FILTER]
500 --excl Exclude tickets whose fields match this string (filter-out)
501 --incl Include tickets whose fields match this string
502
503[--resolved]
504 --resolved-is-empty
505 --resolved-start Query by date range
506 --resolved-end Query by date range
507 --resolved(-not)-empty Query for (closed)/open tickets
508 --resolved-excl Types to exclude
509 --resolved-incl Types to include
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400510 --resolved-in {start} {end} Helps resolve join({and,or}) ambiguity
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500511
512[RANGE]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400513 --newer [d] Search for tickets created < [n] days ago.
514 --older [d] Search for tickets created > [n] days ago.
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500515
516[ALIASES]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400517 --all Query for all unresolved tickets
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400518 --unresolved Alias for --resolved-is-empty
519 --wip Alias for --resolved-is-empty
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400520
521[TOPIC]
522 --fixversion Query by field: fixedversion
523 --resolved Query by field: resolved
524 --user Query by owner, requestor or 'my' jira tickets.
525
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400526[USER]
527 --user [u] Login of user to query for
528 --assigned Query for tickets assigned to the user
529 --reported Query for tickets reported by the user
530
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400531[HELP]
532 --help This message
533 --help-{topic} Display switch help and use case. (--help-resolved)
534 --usage-{topic} Display use cases for a given switch (--usage-user)
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500535
536[USAGE]
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400537 $0 --opencord --assigned --unresolved
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500538 o Display all tickets assigned to my login
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400539
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500540 $0 --reported --or --text 'bbsim' --text 'release'
541 o Search for tickets that contain strings bbsim or release
542 $0 --cord --text-and 'release' --text-and 'voltctl'
543 o Search jira.opencord for tickets that contain release and voltctl
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500544
545 $0 --cord --label failing --label pod
546 o Search jira.opencord for tests failing due to pod/hardware issuses.
547
548 $0 --proj VOL --fixversion "VOLTHA v2.12" --resolved-is-empty
549 o Query for unresolved release tickets
550EOH
551
552 return
553}
554
555## --------------------------------------------------------------------
556# classpath=$(join_by ':' "${mypath[@]}")
557## --------------------------------------------------------------------
558function join_by()
559{
560 local d=${1-} f=${2-}; if shift 2; then printf %s "$f" "${@/#/$d}"; fi;
561}
562
563##----------------##
564##---] MAIN [---##
565##----------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400566declare -a suffix0=() # accumulated terms to join
567declare server='jira.opencord.org'
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500568
569# declare -g -i debug=1
570
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400571unset attrs
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500572while [ $# -gt 0 ]; do
573
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500574 arg="$1"; shift
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400575 banner "ARG=[$arg], \$@=[$@]"
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400576
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500577 [[ -v debug ]] && echo "** argv=[$arg] [$*]"
578
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400579 getopt_detect_modifiers "$arg"
580
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400581 if getopts_switch__not arg; then
582 echo "DETECTED: NOT"
583 declare -i modifier_found=1
584 elif getopts_switch__empty arg; then
585 echo "DETECTED: EMPTY"
586 declare -i modifier_found=1
587 else
588 declare -i modifier_found=0
589 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500590
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400591 if [[ $modifier_found -eq 1 ]]; then
592 echo "*ATTRS MODIFIER (LINENO:$LINENO): $(declare -p attrs)"
593 declare -a args=()
594 [[ ${#arg} -gt 0 ]] && { args+=("$arg"); }
595 [[ $# -gt 0 ]] && { args+=("$@"); }
596 set -- "${args[@]}"
597 continue
598 fi
599
600 case "$arg" in
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400601 '--help') usage; exit 0 ;;
602 '--help-'*) help_with "${arg/--help-/}" ;;
603 '--usage-'*) help_usage_show "${arg/--usage-/}" ;;
Joey Armstrong6890fa92024-08-15 12:14:37 -0400604
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400605
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500606 ##-----------------##
607 ##---] MODES [---##
608 ##-----------------##
609 -*debug) declare -g -i debug=1 ;;
610 --dry-run) declare -g -i dry_run=1 ;;
611
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400612 ##------------------------##
613 ##---] SWITCH ALIAS [---##
614 ##------------------------##
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400615 '--unresolved'|'--wip')
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400616 declare -a args=()
617 args+=('--resolved-is-empty')
618 [[ $# -gt 0 ]] && { args+=("$@"); }
619 set -- "${args[@]}"
620 ;;
621
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500622 ##-------------------##
623 ##---] BY USER [---##
624 ##-------------------##
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400625 '--assigned') declare -g -i argv_assigned=1 ;;
626 '--reported') declare -g -i argv_reported=1 ;;
627 '--me')
628 declare -a args=()
629 args+=('--user' 'currentUser()')
630 args+=('--assigned')
631 args+=('--reported')
632 [[ $# -gt 0 ]] && { args+=("$@"); }
633 set -- "${args[@]}"
634 ;;
635
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500636 --nobody) declare -g -i argv_nobody=1 ;;
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400637 '--user')
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500638 arg="$1"; shift
639 declare -g argv_user="$arg"
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400640
641 [[ ! -v argv_users ]] && { declare -g -a argv_users=(); }
642 argv_users+=("$arg")
643 declare -p argv_users
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500644 ;;
645
646 ##------------------##
647 ##---] SERVER [---##
648 ##------------------##
Joey Armstrong76f861a2024-03-13 16:01:24 -0400649 --serv*)
650 arg="$1"; shift
651 case "$arg" in
652 *cord*) server='jira.opencord.org' ;;
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400653 *onf*) server='jira.opennetworking.org' ;;
654 *) error "--server [$arg] expected opencord or onf" ;;
Joey Armstrong76f861a2024-03-13 16:01:24 -0400655 esac
656 ;;
657
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400658 --onf) declare server='jira.opennetworking.org' ;;
Joey Armstrongcc24b3c2024-03-22 11:12:23 -0400659 --opencord) declare server='jira.opencord.org' ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500660
661 ##---------------------##
662 ##---] SEARCH-BY [---##
663 ##---------------------##
664 --component|--comp*)
665 arg="$1"; shift
666 [[ ! -v components ]] && declare -g -a components=()
667 components+=("$arg")
668 ;;
669
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400670 '--label-is-empty') is_empty+=('label') ;;
671
672 '--label'|'--lab'*)
673 val="$1"; shift
674 if [[ -v getopt_argv_EXCL ]]; then
675 labels_excl+=("$val")
676 elif [[ -v getopt_argv_INCL ]]; then
677 labels_incl+=("$val")
678 else
679 labels_incl+=("$val")
680 fi
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500681 ;;
682
683 ##-----------------------##
684 ##---] Text Search [---##
685 ##-----------------------##
686 # jsearch.sh --text-and bbsim --text-and release
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400687 '--tex'*)
688 [[ $# -gt 0 ]] && { val="$1"; }
689 case "$arg" in
690 '--text-and') text_and+=("$val") ;;
691 '--text-or') text_or+=("$val") ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500692
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400693 # % js --and --text jenkins --text cord
694 # text ~ "Jira Software" # [WORDs]
695 # text ~ "\"Jira Software\"" # [STRING]
696 '--text')
697 if [[ ! -v bool_and_or ]]; then
698 error "Qualify [$arg] using --text-{and,or}"
699 elif [[ bool_and_or -eq 1 ]]; then
700 text_and+=("$1"); shift
701 elif [[ bool_and_or -eq 0 ]]; then
702 text_or+=("$1"); shift
703 else
704 error "Qualify [$arg] using --text-{and,or}"
705 fi
706 ;;
707 *) error "Qualify [$arg] using --text-{and,or}" ;;
708 esac
709 shift # $val
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500710 ;;
711
712 --all) set -- '--resolved-is-none' "$@" ;; # alias: --[un-]resolved
Joey Armstrong76f861a2024-03-13 16:01:24 -0400713 --todo) source "${pgm_lib}/todo.sh" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500714
715 --proj*) projects+=("$1"); shift ;;
716
717 --fixversion-*)
718 # function get_jql_fixversion()
719 case "$arg" in
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400720 *excl)
721 [[ ! -v fixversion_excl ]] && { declare -g -a fixversion_excl=(); }
722 val="\"$1\""; shift
723 html_encode val
724 fixversion_excl+=("$val");
725 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500726
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400727 *incl)
728 [[ ! -v fixversion_incl ]] && { declare -g -a fixversion_incl=(); }
729 val="\"$1\""; shift
730 html_encode val
731 fixversion_incl+=("$val");
732 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500733
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400734 *not-empty) declare -g -i fixversion_not_empty=1 ;;
735 *is-empty) declare -g -i fixversion_is_empty=1 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500736
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400737 *) error "Detected invalid --fixversion-* modifier" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500738 esac
739 ;;
740
Joey Armstrong6890fa92024-08-15 12:14:37 -0400741 '--resolved'*) # [-+]
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400742
743 gen_attrs__empty 'resolved'
744
745 # [[ -v resolved_not_empty ]] && { declare -p resolved_not_empty; }
746 # [[ -v resolved_is_empty ]] && { declare -p resolved_is_empty; }
747
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500748 # function get_jql_reasons()
749 case "$arg" in
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400750 '--resolved') ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500751
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400752 *'start') declare -g resolved_start="$1"; shift ;;
753 *'end') declare -g resolved_end="$1"; shift ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500754
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400755 *'excl')
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400756 [[ ! -v resolved_excl ]] && { declare -g -a resolved_excl=(); }
757 val="\"$1\""; shift
758 html_encode val
759 resolved_excl+=("$val");
760 ;;
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400761 *'incl')
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400762 [[ ! -v resolved_incl ]] && { declare -g -a resolved_incl=(); }
763 val="\"$1\""; shift
764 html_encode val
765 resolved_incl+=("$val");
766 ;;
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400767
768 *) error "Detected invalid --resolved-* modifier arg=[$arg]" ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500769 esac
770 ;;
771
772 -*newer)
773 arg="$1"; shift
774 suffix0+=("created <= '-${arg}d'") ;;
775
776 -*older)
777 arg="$1"; shift
778 suffix0+=("created >= '-${arg}d'") ;;
779
780 ##----------------##
781 ##---] BOOL [---##
782 ##----------------##
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400783 --[aA][nN][dD])
784 declare -g -i bool_and=1
785 declare -g -i bool_and_or=1 # ! -v else toggle
786 ;;
787 --[oO][rR])
788 declare -g -i bool_or=1
789 declare -g -i bool_and_or=0
790 ;;
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500791
792 ##------------------##
793 ##---] MEMBER [---##
794 ##------------------##
795 --[iI][nN]) declare -g -i bool_in=1 ;;
796 --[nN][oO][tT]) declare -g -i bool_not=1 ;;
797
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400798 [A-Z][A-Z][A-Z]-[0-9]*) # VOL-xxxx (jira ticket)
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500799 case "$arg" in
800 CORD-[0-9]*)
801 url="https://jira.opencord.org/browse/${arg}"
802 urls_raw+=('--new-window' "$url")
803 ;;
804
805 INF-[0-9]*)
806 url="https://jira.opennetworking.org/browse/${arg}"
807 urls_raw+=('--new-window' "$url")
808 ;;
809
810 VOL-[0-9]*)
811 url="https://jira.opencord.org/browse/${arg}"
812 urls_raw+=('--new-window' "$url")
813 ;;
814
815 *) error "Detected invalid ticket [$arg]" ;;
816
817 esac
818 ;;
819
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400820 ## ---------------------------
821 ## Search all fields for value
822 ## ---------------------------
823 [[:word:]]*)
824
825 echo "MATCHED: [$arg] (LINENO: $LINENO)"
826 declare -a args=()
827 args+=('--OR')
828 args+=('--component' "$arg")
829 args+=('--label-incl' "$arg")
830 args+=('--text-or' "$arg")
831 [[ $# -gt 0 ]] && { args+=("$@"); }
832 set -- "${args[@]}"
833 ;;
834
835 -*) error "Detected unknown switch [$arg]" ;;
836
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500837 # -----------------------------------------------------------------------
838 # https://support.atlassian.com/jira-software-cloud/docs/search-syntax-for-text-fields/
839 # -----------------------------------------------------------------------
840 # +jira atlassian -- must contain jira, atlassian is optional
841 # -japan -- exclude term
842 # [STEM] summary ~ "customize" -- finds stem 'custom' in the Summary field
843 *)
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400844 echo "MATCHED: [$arg] (LINENO: $LINENO)"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500845 declare -p text_and
846 error "Detected unknown argument $arg"
847 ;;
848 esac
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400849
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400850
851 if [[ -v resolved ]]; then
852 clear_attrs__empty
853 fi
854
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500855done
856
Joey Armstrong76f861a2024-03-13 16:01:24 -0400857## --------------
858## Required check
859## --------------
860[[ ! -v server ]] && { error "--server={cord,onf} is required"; }
861
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500862## ----------------------
863## Construct query filter
864## ----------------------
865do_user suffix0
866do_projects suffix0
867[[ -v components ]] && { do_components components suffix0; }
868do_labels labels_incl labels_excl suffix0
869do_text text suffix0
Joey Armstrong6890fa92024-08-15 12:14:37 -0400870get_jcl_resolved suffix0
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400871
Joey Armstrong6890fa92024-08-15 12:14:37 -0400872
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500873do_fixversion suffix0
874
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400875[[ -v getopt_argv_any_OR ]] && { declare -p getopt_argv_any_OR; }
876
Joey Armstrong6890fa92024-08-15 12:14:37 -0400877if [[ -v getopt_argv_any_OR ]]; then
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400878 query="$(join_by ' OR ' "${suffix0[0]}")"
Joey Armstrong6890fa92024-08-15 12:14:37 -0400879elif [[ -v getopt_argv_any_AND ]]; then
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400880 query="$(join_by ' AND ' "${suffix0[0]}")"
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400881else
Joey Armstrongf8c78f02024-08-28 17:00:29 -0400882# query="$(join_by ' OR ' "${suffix0[0]}")"
883 error "Ambiguous query [argv needs: --and or --or], argv=[$*]"
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400884fi
885
Joey Armstrong9cbbf7f2024-08-14 17:05:18 -0400886
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500887filter=''
888gen_filter filter suffix0
889
890if [[ ! -v urls_raw ]]; then
891 url=''
892 gen_url url filter
893 urls_filt+=("$url")
894elif [ ${#urls_raw} -eq 0 ]; then
895 url=''
896 gen_url url filter
897 urls_filt+=("$url")
898fi
899
900[[ -v debug ]] && [[ -v url ]] && echo "URL: $url"
Joey Armstronge4ef06a2024-03-22 11:43:54 -0400901browser="${BROWSER:-firefox}"
Joey Armstrong3134bfd2024-02-10 20:51:25 -0500902echo "$browser ${urls_filt[@]} ${urls_raw[@]}"
903
904if [[ ! -v dry_run ]]; then
905 "$browser" "${urls_filt[@]}" "${urls_raw[@]}" >/dev/null 2>/dev/null &
906fi
907
908# [SEE ALSO]
909# o https://support.atlassian.com/jira-software-cloud/docs/advanced-search-reference-jql-fields/
910
911# [EOF]