Add command line tool gerrit.sh
Change-Id: I264237c98f89163febd7a6458e6e39944769158f
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..d60519b
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,6 @@
+[gerrit]
+host=gerrit.opencord.org
+port=29418
+project=onf-scripts.git
+defaultremote=origin
+defaultbranch=master
diff --git a/bin/gerrit.sh b/bin/gerrit.sh
new file mode 120000
index 0000000..8f6eac3
--- /dev/null
+++ b/bin/gerrit.sh
@@ -0,0 +1 @@
+../gerrit/gerrit.sh
\ No newline at end of file
diff --git a/gerrit/gerrit.sh b/gerrit/gerrit.sh
new file mode 100755
index 0000000..adabf93
--- /dev/null
+++ b/gerrit/gerrit.sh
@@ -0,0 +1,533 @@
+#!/bin/bash
+## -----------------------------------------------------------------------
+## Intent: Construct gerrit server queries and URLs based on arguments
+## -----------------------------------------------------------------------
+
+{ # loader
+ declare pgm=''
+ pgm="$(realpath --canonicalize-existing "$0")"
+ root="${pgm%/*}" # path -= /bin/
+ root="${root%/*}" # path is parent
+ source "$root/lf/onf-common/common.sh" '--common-args-begin--'
+
+ # lib_root="${pgm/.sh}" gerrit.sh => gerrit/
+}
+
+##-------------------##
+##---] GLOBALS [---##
+##-------------------##
+declare -g serv='gerrit.opencord.org'
+declare -x -g BROWSER="${BROWSER:-opera}"
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function error_orig()
+{
+ echo "${FUNCNAME[1]} ERROR: $*"
+ exit 1
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function join_by_orig()
+{
+ local d=${1-} f=${2-}; if shift 2; then printf %s "$f" "${@/#/$d}"; fi;
+}
+
+## -----------------------------------------------------------------------
+## Usage: $0 --repo voltha-go --search --wip
+## -----------------------------------------------------------------------
+function do_gerrit_search()
+{
+ local -n ref_urls=$1 ; shift
+ local -n ref_repos=$1 ; shift
+ local -n ref_status=$1 ; shift
+
+ # local stem='https://gerrit.opencord.org/q/project:voltha-go+status:open'
+ local stem='https://gerrit.opencord.org/q/'
+
+ local repo
+ for repo in "${ref_repos[@]}";
+ do
+ local -a args=()
+ args+=("project:${repo}")
+
+ if [[ -v argv_me ]]; then
+ args+=("owner:${USER}@opennetworking.org")
+ fi
+
+ local status
+ for status in "${ref_status[@]}";
+ do
+ args+=("$status")
+ done
+
+ local url="$stem"
+ url+="$(join_by '+' "${args[@]}")"
+ ref_urls+=("$url")
+ done
+
+
+
+ # --debug) declare -g -i debug=1 ;;
+ # --search) declare -g -i search=1 ;;
+ # --wip) declare -g -i status_is_open=1 ;;
+}
+
+
+## -----------------------------------------------------------------------
+## Intent: Iterate over --admin values and generate repositories
+## -----------------------------------------------------------------------
+function gen_admin_urls()
+{
+ local -n ref=$1 ; shift
+ local -n _repos=$1 ; shift
+ local -n _admins=$1 ; shift
+
+ local repo
+ for repo in "${_repos[@]}";
+ do
+ local attr
+ for admin in "${_admins[@]}";
+ do
+ # https://gerrit.opencord.org/admin/repos/voltha-go
+ case "$admin" in
+ branches)
+ ref+=("https://gerrit.opencord.org/admin/repos/${repo},branches")
+ ;;
+ tags)
+ ref+=("https://gerrit.opencord.org/admin/repos/${repo},tags")
+ ;;
+ *) error "Unknown --admin type [$admin]" ;;
+ esac
+
+ done # admins[@]
+ done # repos[@]
+ return
+}
+
+## -----------------------------------------------------------------------
+## Intent: Iterate over --admin values and generate repositories
+## -----------------------------------------------------------------------
+function gen_view_urls()
+{
+ local -n ref=$1 ; shift
+ local -n _repos=$1 ; shift
+ local -n _views=$1 ; shift
+
+ local -a view_keys=("${!_views[@]}")
+ local stem0="https://gerrit.opencord.org/plugins/gitiles"
+
+ # https://gerrit.opencord.org/plugins/gitiles/ofagent-go
+
+ local repo
+ for repo in "${_repos[@]}";
+ do
+ declare -p repo
+ local stem="${stem0}/$repo"
+ local view
+ for view in "${view_keys[@]}";
+ do
+ declare -p view
+ # https://gerrit.opencord.org/admin/repos/voltha-go
+ case "$view" in
+ # https://gerrit.opencord.org/plugins/gitiles/voltha-system-tests
+ search) continue ;;
+ default) ref+=("$stem") ;;
+ # repo*) ref+=("$stem/$repo") ;;
+ repo*) ref+=("$stem") ;;
+ master)
+ ref+=("$stem/+/refs/heads/master")
+ ;;
+
+ voltha-*)
+ echo "STEM: $stem"
+ if false; then
+ ref+=("$stem/+/refs/tags/${view}")
+ ref+=("$stem/+/refs/heads/${view}")
+ fi
+ # ref+=("$stem/+/refs/heads/${view}")
+ ref+=("$stem/+/refs/heads/${view}")
+ ;;
+
+ v*) ref+=("$stem/+/refs/tags/${view}") ;;
+ *) error "Unknown --view type [$view]" ;;
+ esac
+ done # views[@]
+ done # repos[@]
+
+ for r in "${ref[@]}";
+ do
+ echo "REPO: $r"
+ done
+
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function get_urls()
+{
+ local -n ref="$1"; shift
+ local _srv="$1"; shift
+
+ local gerrit="https://${_srv}"
+ ref=(\
+ ['admin']="$gerrit/admin/repos"
+ ['base']="$gerrit"\
+ ['dashboard']="$gerrit/dashboard/self"\
+ )
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function changeset()
+{
+ local _repo="$1"; shift
+ local _id="$1"; shift
+ local -n ref=$1; shift
+
+ local url="https://gerrit.opencord.org/c/${repo}/+/${id}"
+ ref+=("$url")
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function browse()
+{
+ local -n _urls=$1; shift
+
+ # declare -p _urls
+ # echo "${_urls[@]}"
+ "${BROWSER}" "${_urls[@]}" >/dev/null 2>/dev/null &
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function access_url()
+{
+ local -n ref=$1; shift
+ local _repo="$1"; shift
+
+ declare -A data=()
+ get_urls data "$serv"
+
+ # declare -p data | tr '=' '\n'
+ # ref+=("https://gerrit.opencord.org/admin/repos/${_repo},access")
+ ref+=("${data['admin']}/${_repo},access")
+
+ # browse urls
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function branch_url()
+{
+ local _repo="$1"; shift
+ local -a urls=()
+ urls+=("https://gerrit.opencord.org/admin/repos/${_repo},branches")
+ browse urls
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function do_gerrit_dashboard()
+{
+ local -n ref=$1; shift
+
+ declare -A data=()
+ get_urls data "$serv"
+ ref+=("${data['dashboard']}")
+ return
+}
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+function usage()
+{
+ cat <<EOH
+Usage: $0
+ --all r Load all metadata for a repository
+ --reviews Load pending code review requests
+
+ --access Display gerrit ACLs
+ --dash(boad) Display my patch dashboard
+ --branch Admin branch URL
+
+ --crowd View crowd access roles for group
+ --crowd-all Group search (crowd)
+
+ --groups [g] View access roles for group.
+ --groups-all Group search (gerrit)
+
+ --repo Repository name
+ --serv Gerrit server name
+
+ --me Query for my patches
+ --wip
+ --search
+
+ --admins a
+ a=branches View repository branches
+ a=tags View repository tags
+
+ --patch [repo] Search for repository patches
+ --version v Artifact versions(s) to act on
+ v=master Mainline development
+ v=voltha-2.12 Artifact branch from a release
+ v=v2.12.0 Artifact tag derived from a release
+ v=v3.5.4 Artifact tag derived from VERSION file
+
+ --view v View a code repository:
+ repo View top level gerrit repository page (w/branch & tag)
+ search Gerrit repo search page
+ master View a branch
+ voltha-2.12 View a branch
+ v2.3.3 View a tag
+
+[FILTERS]
+ --status s Filter query by open/merge/closed status
+ s=open (is:open)
+ s=merged
+
+ --debug
+ --help
+
+% gerrit.sh --repo voltha-go --admin tags --admin branches
+
+## Search for umerged patches in repo:voltha-go
+% gerrit.sh --repo voltha-go --search --wip
+EOH
+ return
+}
+
+#
+
+# https://gerrit.opencord.org/q/status:open+-is:wip
+
+# repo=''
+declare -a urls=()
+
+##----------------##
+##---] MAIN [---##
+##----------------##
+[[ $# -eq 0 ]] && { set -- '--help'; }
+
+while [ $# -ne 0 ]; do
+ arg="$1"; shift
+ case "$arg" in
+ --help) usage; exit 0 ;;
+
+ ## Modes
+ --debug)
+ declare -g -i argv_debug=1
+ declare -g -i debug=1
+ ;;
+ --search) declare -g -i argv_search=1 ;;
+ --me) declare -g -i argv_me=1 ;;
+
+ --wip)
+ [[ ! -v argv_status ]] && { declare -g -a argv_status=(); }
+ argv_status+=('status:open')
+ ;;
+
+ --admin)
+ [[ ! -v admins ]] && { declare -a admins=(); }
+ arg="$1"; shift
+ case "$arg" in
+ br*) admins+=('branches') ;;
+ ta*) admins+=('tags') ;;
+ *) error "Unknown --attr value [$attr]" ;;
+ ## Also master and voltha-2.12
+ # https://gerrit.opencord.org/plugins/gitiles/voltha-go/+/refs/heads/voltha-2.12
+ esac
+ ;;
+
+ --all)
+ repo="$1"; shift
+ declare -a args=()
+ args+=('--repo' "$repo")
+ #
+ args+=('--admin' 'branches')
+ args+=('--admin' 'tags')
+
+ # args+=('--view') # post getopts expansion
+ # if @versions() else master
+ if [[ ${#versions[@]} -eq 0 ]]; then
+ versions+=('master')
+ fi
+
+# args+=('--view' 'voltha-2.11')
+ args+=('--view' 'voltha-2.12')
+ set -- "${args[@]}" "$@"
+ ;;
+
+ --repo)
+ repo="$1"; shift
+ [[ ! -v repos ]] && { declare -a repos=(); }
+ repos+=("$repo")
+ ;;
+
+ --serv) serv="$1"; shift
+ case "$serv" in
+ *cord*) serv='gerrit.opencord.org' ;;
+ *onos*) serv='gerrit.onosproject.org' ;;
+ *) error "Detected invalid --serv $serv" ;;
+ esac
+ ;;
+
+ --access)
+ [[ ! -v repo ]] && { error "--repo is required"; }
+ access_url urls "$repo"
+ ;;
+
+ --branch)
+ [[ ! -v repo ]] && { error "--repo is required"; }
+ branch_url "$repo"
+ ;;
+
+ --crowd*)
+ # https://crowd.opennetworking.org/crowd/console/secure/group/browse.action?directoryId=163841&updateSuccessful=
+ declare https='https://crowd.opennetworking.org'
+ declare base_url="${https}/crowd/console/secure/group/browse.action"
+ case "$arg" in
+ --crowd-*)
+ # urls+=("${base_url}?directoryId=163841&updateSuccessful=")
+ urls+=("${base_url}")
+ ;;
+ *)
+ # https://crowd.opennetworking.org/crowd/console/secure/group/browse.action?search=%22VOLTHACore%22
+ [[ $# -eq 0 ]] && { error "--crowd requires an argument"; }
+ arg="$1"; shift
+ urls+=("${base_url}?search=%22${arg}%22")
+ ;;
+ esac
+ ;;
+
+ --dash*) do_gerrit_dashboard urls ;;
+
+ #
+ --group*)
+ case "$arg" in
+ --group*)
+ urls+=("https://${serv}/admin/groups")
+ ;;
+ *)
+ [[ $# -eq 0 ]] && { error "--group requires an argument"; }
+ arg="$1"; shift
+ urls+=("https://${serv}/admin/groups/q/filter:${arg}}")
+ ;;
+ esac
+ ;;
+
+ --id)
+ id="$1"; shift
+ [[ ${#repo} -eq 0 ]] && { error "--repo is required"; }
+ changeset "$repo" "$id" urls
+ ;;
+
+ --status)
+ status="$1"; shift # open, closed, merged
+ urls[-1]+="+status:${status}"
+ ;;
+
+ --patch*)
+ repo="$1"; shift
+ urls+=("https://gerrit.opencord.org/q/${repo}+stats:open")
+ # https://gerrit.opencord.org/q/voltha-openolt-adapter-go
+ ;;
+ --review)
+ urls+=('https://gerrit.opencord.org/c/aether-ci-management/+/34900')
+ ;;
+
+ --ver*)
+ [[ $# -eq 0 ]] && { error "Usage: $arg [str]"; }
+ arg="$1"; shift
+ [[ ! -v versions ]] && { declare -a versions=(); }
+ versions+=("$arg")
+ ;;
+
+ # post getopt expansion to support --version x --version y
+ --view)
+ [[ $# -eq 0 ]] && { set -- '--default'; }
+ arg="$1"; shift
+ # [[ "${#views[@]}" -gt 0 ]]
+ [[ ! -v views ]] && { declare -A views=(); }
+ case "$arg" in
+
+ search*)
+ urls+=('https://gerrit.opencord.org/admin/repos')
+ ;;
+
+ repo) views['repository']=1 ;;
+
+ # https://gerrit.opencord.org/plugins/gitiles/voltha-go
+ master) views['master']=1 ;;
+ voltha*) views["$arg"]=1 ;;
+ v*) views["$arg"]=1 ;;
+ *)
+ # Missing latest tags
+ views['default']=1
+ views['master']=1
+ ;;
+ esac
+ ;;
+
+ -*)
+ echo "ERROR: Unknown argument [$arg]"
+ exit 1
+ ;;
+
+ [[:alnum:]]*)
+ declare -a what=()
+ # whats+=('patches')
+ whats+=('versions')
+
+ stem="https://gerrit.opencord.org/q/${arg}"
+
+ for what in "${whats[@]}";
+ do
+ case "$what" in
+ patches) urls+=("https://gerrit.opencord.org/q/${arg}") ;;
+ versions)
+ urls+=("https://gerrit.opencord.org/plugins/gitiles/${arg}/+/refs/heads/master/VERSION")
+ # urls+=("https://gerrit.opencord.org/plugins/gitiles/${arg}/+/refs/tags/v0.3.6/VERSION")
+ urls+=("https://gerrit.opencord.org/plugins/gitiles/${arg}/+/refs/heads/voltha-2.12/VERSION")
+ ;;
+ '??') urls+=("https://gerrit.opencord.org/plugins/gitiles/${arg}") ;;
+ *) urls+=("https://gerrit.opencord.org/q/${arg}") ;;
+ esac
+ done
+ esac
+done
+
+[[ -v argv_search ]] && { do_gerrit_search urls repos argv_status; }
+
+[[ -v admins ]] && { gen_admin_urls urls repos admins; }
+
+## are --views working ?
+[[ "${#views[@]}" -gt 0 ]] && { gen_view_urls urls repos views; }
+# [[ ! -v views ]] && { echo 'called'; gen_view_urls urls repos views; }
+
+[[ -v debug ]] && { echo "$BROWSER" "${urls[@]}"; }
+# "$BROWSER" "${urls[@]}" >/dev/null 2>/dev/null
+[[ -v argv_debug ]] && { set -x; }
+"$BROWSER" "${urls[@]}"
+[[ -v argv_debug ]] && { set +x; }
+
+## -----------------------------------------------------------------------
+## [TODO]
+## Query patches by repo:voltha-lib-go
+## ssh gerrit.opencord.org gerrit query --patch-sets projects:voltha-lib-go | grep -i description
+# ssh gerrit.opencord.org gerrit query --patch-sets 'projects:voltha-lib-go AND status:open limit:2' |
+
+# Show URL and Commit message
+# ssh gerrit.opencord.org gerrit query --format=JSON --patch-sets 'projects:voltha-lib-go AND status:open limit:2' | jq '.url,.commitMessage'
+## -----------------------------------------------------------------------
+
+# [EOF]