Add gerrit plugin
Use gerrit plugin to look up references based of change ids, update patch sets and more.
This commit is contained in:
parent
96e4e5dd03
commit
65bca8c107
186
plugins/gerrit/gerrit.plugin.zsh
Normal file
186
plugins/gerrit/gerrit.plugin.zsh
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Need to export url for your gerrit, example
|
||||||
|
# export GERRIT_URL=https://review.openstack.org
|
||||||
|
#
|
||||||
|
# Your git config will also need to contain you gerrit username, you can set it with
|
||||||
|
# git config --global gitreview.username
|
||||||
|
# or
|
||||||
|
# export GERRIT_USERNAME=yourusername
|
||||||
|
#
|
||||||
|
# To use any of the more advanced commands you will need to have you ssh key
|
||||||
|
# added to gerrit as this plugin uses gerrits ssh API
|
||||||
|
#
|
||||||
|
# Example usage:
|
||||||
|
#
|
||||||
|
# Fetch patch and apply it to the repo in directory tripleo-heat-templates
|
||||||
|
# $ gerrit-patch 38409 tripleo-heat-templates
|
||||||
|
# Fetch patch 38676 and apply it to the current directory/repo
|
||||||
|
# $ gerrit-patch 38676
|
||||||
|
#
|
||||||
|
# $ gerrit-get-latest-patch
|
||||||
|
|
||||||
|
|
||||||
|
# Download latest patchset from change number given. This will not apply the patch, it will however
|
||||||
|
# be stored in FETCH_HEAD to be applied.
|
||||||
|
#
|
||||||
|
# $1 change number
|
||||||
|
# $2 dir name (optional, will use current dir if not provided)
|
||||||
|
function gerrit-fetch-patch()
|
||||||
|
{
|
||||||
|
if [[ -z "${GERRIT_URL}" ]]; then echo "GERRIT_URL must be set"; return 1; fi
|
||||||
|
local git_dir repo_url repo_tmp ref
|
||||||
|
git_dir="${2:-$(pwd)}"
|
||||||
|
repo=$(repo-name "${git_dir}")
|
||||||
|
ref=$(git ls-remote ${GERRIT_URL}/${repo} | cut -f2 | grep ${1} | sort -rnt '/' -k 5 | head -n1)
|
||||||
|
if [[ -z "${ref}" ]]; then echo "No reference to patch ${1} found on ${GERRIT_URL}"; return 1; fi
|
||||||
|
echo "Change ${1} in ${repo} has lastest ref: ${ref}"
|
||||||
|
git -C "${git_dir}" fetch ${GERRIT_URL}/${repo} ${ref}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Echo change id of HEAD
|
||||||
|
#
|
||||||
|
# $1 git reference
|
||||||
|
# $2 dir name
|
||||||
|
function gerrit-change-id()
|
||||||
|
{
|
||||||
|
local git_dir="${2:-$(pwd)}"
|
||||||
|
git -C "${git_dir}" --no-pager log -1 --format="%b" "${1}" | awk '/[cC]hange-[iI]d:/{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Echo repo name, only will work with repo names with two fields i.e. openstack/nova
|
||||||
|
#
|
||||||
|
# $1 dir name
|
||||||
|
function repo-name()
|
||||||
|
{
|
||||||
|
local git_dir repo_url repo_tmp
|
||||||
|
git_dir="${1:-$(pwd)}"
|
||||||
|
repo_url="$(git -C "${git_dir}" remote -v | head -n1 | cut -f2 | cut -d' ' -f1)"
|
||||||
|
repo_tmp="${repo_url%/*}"
|
||||||
|
echo "${repo_tmp##*/}/${repo_url##*/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch the latest patchset for the change number given and apply it to the repo
|
||||||
|
#
|
||||||
|
# $1 change number
|
||||||
|
# $2 dir name (optional, will use current dir if not provided)
|
||||||
|
function gerrit-patch()
|
||||||
|
{
|
||||||
|
local git_dir="${2:-$(pwd)}"
|
||||||
|
gerrit-fetch-patch "${1}" "${git_dir}"
|
||||||
|
git -C "${git_dir}" cherry-pick FETCH_HEAD
|
||||||
|
}
|
||||||
|
|
||||||
|
# List open patches in the gerrit system
|
||||||
|
# Print output in JSON
|
||||||
|
function gerrit-list-open-patches()
|
||||||
|
{
|
||||||
|
if [[ -z "${GERRIT_URL}" ]]; then echo "GERRIT_URL must be set"; return 1; fi
|
||||||
|
local json gerrit_user
|
||||||
|
gerrit_user=$(gerrit-username)
|
||||||
|
if [[ -z "${gerrit_user}" ]]; then return 1; fi
|
||||||
|
json=$(gerrit-ssh-query "--current-patch-set status:open owner:${gerrit_user}")
|
||||||
|
jq -s '.[]|select(.subject)|{subject, project, number, id, "url":"'${GERRIT_URL}'/#/c/\(.number)", reviews:[.currentPatchSet.approvals[]|{by: .by.username, value}]}' <<< $json
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Used to acommplish more complex gerrit queries. Requires ssh key to be added to gerrit.
|
||||||
|
# Ouput is in JSON format.
|
||||||
|
# See https://review.openstack.org/Documentation/cmd-index.html for more detail.
|
||||||
|
#
|
||||||
|
# $1 gerrit query string
|
||||||
|
function gerrit-ssh-query()
|
||||||
|
{
|
||||||
|
if [[ -z "${GERRIT_URL}" ]]; then echo "GERRIT_URL must be set"; return 1; fi
|
||||||
|
local gerrit_user=$(gerrit-username)
|
||||||
|
if [[ -z "${gerrit_user}" ]]; then return 1; fi
|
||||||
|
ssh -p 29418 ${gerrit_user}@${GERRIT_URL##*//} "gerrit query --format=JSON ${1}" | tee /tmp/gerritquery.json
|
||||||
|
}
|
||||||
|
|
||||||
|
function gerrit-username()
|
||||||
|
{
|
||||||
|
local gerrit_user=${GERRIT_USERNAME:-"$(git config gitreview.username)"}
|
||||||
|
if [[ -z "${gerrit_user}" ]]; then
|
||||||
|
echo "Gerrit username not found" 1>&2
|
||||||
|
echo "Please export GERRIT_USERNAME" 1>&2
|
||||||
|
echo "Or set 'git config --global gitreview.username'" 1>&2
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo "${gerrit_user}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# Lookup what patchset a change id belongs to.
|
||||||
|
# Prints JSON
|
||||||
|
#
|
||||||
|
# $1 git dir (optional)
|
||||||
|
# $2 optional ref, defaults to HEAD.
|
||||||
|
function gerrit-patch-from-ref
|
||||||
|
{
|
||||||
|
local git_dir ref cid
|
||||||
|
git_dir="${1:-$(pwd)}"
|
||||||
|
ref=${2:-HEAD}
|
||||||
|
cid=$(gerrit-change-id ${ref} "${git_dir}")
|
||||||
|
gerrit-ssh-query "${cid}" | jq -s '.[0]|select(.subject)|{subject, project, number, id, "url":"'${GERRIT_URL}'/#/c/\(.number)"}'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Using HEAD get the changeid and find the latest patchset of this change and apply it
|
||||||
|
#
|
||||||
|
# $1 optional git dir
|
||||||
|
function gerrit-get-latest-patchset()
|
||||||
|
{
|
||||||
|
local change_number git_dir
|
||||||
|
git_dir="${1:-$(pwd)}"
|
||||||
|
change_number=$(gerrit-patch-from-ref "${git_dir}" | jq -r .number)
|
||||||
|
gerrit-fetch-patch "${change_number}" "${git_dir}"
|
||||||
|
git -C "${git_dir}" reset --hard HEAD~1
|
||||||
|
git -C "${git_dir}" cherry-pick FETCH_HEAD
|
||||||
|
}
|
||||||
|
|
||||||
|
# Will reset the current branch to HEAD~1 if change id of HEAD matches
|
||||||
|
# that of FETCH_HEAD
|
||||||
|
#
|
||||||
|
# $1 change id
|
||||||
|
# $2 optional dir name
|
||||||
|
function gerrit-reset-and-patch()
|
||||||
|
{
|
||||||
|
local git_dir="${2:-$(pwd)}"
|
||||||
|
gerrit-fetch-patch "${1}" "${git_dir}"
|
||||||
|
|
||||||
|
local cid=$(change-id "HEAD" "${git_dir}")
|
||||||
|
local rcid=$(change-id "FETCH_HEAD" "${git_dir}")
|
||||||
|
if [[ "${cid}" == "${rcid}" ]]; then
|
||||||
|
git -C "${git_dir}" reset --hard HEAD~1
|
||||||
|
fi
|
||||||
|
git -C "${git_dir}" cherry-pick FETCH_HEAD
|
||||||
|
}
|
||||||
|
|
||||||
|
function gerrit-show-patch()
|
||||||
|
{
|
||||||
|
if [[ -z "${GERRIT_URL}" ]]; then echo "GERRIT_URL must be set"; return 1; fi
|
||||||
|
gerrit-ssh-query "${1}" | jq -s '.[0]|select(.subject)|{subject, project, number, id, "url":"'${GERRIT_URL}'/#/c/\(.number)"}'
|
||||||
|
}
|
||||||
|
|
||||||
|
function gerrit-open-patch()
|
||||||
|
{
|
||||||
|
if [[ -z "${GERRIT_URL}" ]]; then echo "GERRIT_URL must be set"; return 1; fi
|
||||||
|
local git_dir ref cid url
|
||||||
|
cid=${1:-$(gerrit-change-id HEAD)}
|
||||||
|
url="$(gerrit-ssh-query "${cid}" | jq -s '.[0]|select(.subject)|"'${GERRIT_URL}'/#/c/\(.number)"')"
|
||||||
|
# :Q will remove wrapping quotes
|
||||||
|
_gerrit-browser-open ${url:Q}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _gerrit-browser-open()
|
||||||
|
{
|
||||||
|
local error_file=$(mktemp -t"gerrit.zsh.errorXXXX")
|
||||||
|
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
||||||
|
open ${1} 2> $error_file
|
||||||
|
else
|
||||||
|
xdg-open ${1} 2> $error_file
|
||||||
|
fi
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
cat $error_file 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user