nutools/repoctl

390 lines
11 KiB
Plaintext
Raw Normal View History

2019-08-25 23:31:25 +04:00
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname -- "$0")/lib/ulib/auto" || exit 1
urequire json
2019-08-25 23:31:25 +04:00
function display_help() {
uecho "$scriptname: piloter un serveur git (gitolite, gogs, gitea, etc.)
USAGE
$scriptname ACTION URL [options]
2019-08-25 23:31:25 +04:00
ACTIONS
2020-09-10 11:15:40 +04:00
u|update-origin URL
Mettre à jour origin dans le dépôt courant avec l'url spécifié
c|create URL [description]
2019-08-25 23:31:25 +04:00
Créer un nouveau dépôt avec la description spécifiée
2020-09-10 11:15:40 +04:00
OPTIONS
-u, --update-origin
mettre à jour origin dans le dépôt courant avec l'url du dépôt
nouvellement créé, comme avec l'action update-origin
2019-08-25 23:31:25 +04:00
2020-09-10 11:15:40 +04:00
l|list URL [VARs...]
Lister les dépôts dans l'organisation spécifiée. Si aucune organisation
n'est spécifiée dans l'url, lister les dépôts *accessibles* par
l'utilisateur (cela inclut les dépôts des organisations auxquelles
l'utilisateur a accès)
VARs est une liste de variables à afficher pour chaque dépôt, séparés
par le caractère tabulation. La valeur par défaut est full_name
2019-08-25 23:31:25 +04:00
2020-09-10 11:15:40 +04:00
g|get URL [VARs...]
2019-10-10 10:24:07 +04:00
Afficher les propriétés du dépôt spécifié. VARs est une liste de
variables à afficher pour le dépôt, séparés par le caractère tabulation.
2020-09-10 11:15:40 +04:00
e|edit URL var=value...
2019-10-10 10:24:07 +04:00
Modifier les propriétés du dépôt. Consulter l'API pour la liste exacte
des propriétés pouvant être modifiées. Avec gitea 1.9.3, il y a au moins
celles-là:
name
description
website
private
default_branch
2020-09-10 11:15:40 +04:00
d|delete URL
Supprimer le dépôt spécifié"
}
2019-08-25 23:31:25 +04:00
function repoctl_init() {
repourl="$1"
2019-08-25 23:31:25 +04:00
[ -n "$repourl" ] || return
rname=
rtype=gitolite
rprefix=
REPO_PREFIXES=()
REPO_TYPES=()
set_defaults repoctl
2019-08-25 23:31:25 +04:00
# Traduire les aliases éventuels
local asrcdest asrc adest
for asrcdest in "${REPO_PREFIXES[@]}"; do
splitfsep "$asrcdest" = asrc adest
if [ "${repourl#$asrc}" != "$repourl" ]; then
newurl="$adest${repourl#$asrc}"
if [ "$newurl" != "$repourl" ]; then
enote "$repourl --> $newurl"
repourl="$newurl"
break
fi
fi
done
local rnametypeprefix tmp found
for rnametypeprefix in "${REPO_TYPES[@]}"; do
splitfsep "$rnametypeprefix" : rname tmp
splitfsep "$tmp" : rtype rprefix
if [ "${repourl#$rprefix}" != "$repourl" ]; then
found=1
break
fi
done
if [ -z "$found" ]; then
rname=
rtype=gitolite
rprefix=
fi
}
function curlto() {
local url="$1"; shift
local payload="$1"; shift
local outfile="$1"; shift
local tmpfile
if [ -z "$outfile" ]; then
ac_set_tmpfile tmpfile
outfile="$tmpfile"
fi
local -a args
local r http_code
args=(-s -w '%{http_code}' -o "$outfile")
[ -n "$payload" ] && args+=(-d "$payload")
[ -n "$HTTP_METHOD" ] && args+=(-X "$HTTP_METHOD")
2019-08-25 23:31:25 +04:00
args+=("$@" "$url")
setx http_code=curl "${args[@]}"
case "$http_code" in
2*) r=0;;
4*) r=1;;
5*) r=3;;
*) r=11;;
esac
if [ -n "$tmpfile" ]; then
cat "$tmpfile"
ac_clean "$tmpfile"
fi
upvar http_code "$http_code"
return "$r"
}
function gogs_setvars() {
gogs_url="${rname}_GOGS_URL"; gogs_url="${!gogs_url}"
gogs_user="${rname}_GOGS_USER"; gogs_user="${!gogs_user}"
gogs_key="${rname}_GOGS_KEY"; gogs_key="${!gogs_key}"
userpath="${repourl#$rprefix}"
splitfsep "$userpath" / user path
}
################################################################################
2020-09-10 11:15:40 +04:00
function _update_origin() {
estep "Mise à jour de l'origine"
git remote set-url origin "${repourl%.git}.git"
2020-09-10 11:15:40 +04:00
}
function _update_origin_push() {
if ask_yesno "Faut-il faire git push?" O; then
git push --all && git push --tags
else
enote "Ne pas oublier de faire 'git push --all && git push --tags'"
fi
}
function _update_origin_pull() {
if ask_yesno "Faut-il faire git pull?" O; then
git pull
else
enote "Ne pas oublier de faire 'git pull'"
fi
}
function update_origin_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_update_origin_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_update_origin_action() {
local repourl
if [ -n "$user" -a "$user" != "$gogs_user" ]; then
# dépôt d'une organisation
repourl="$gogs_url/$user/$path"
else
# dépôt d'un utilisateur
repourl="$gogs_url/$gogs_user/$path"
fi
_update_origin
_update_origin_pull
}
################################################################################
function create_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_create_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_create_action() {
2020-09-08 11:51:40 +04:00
local update_origin="$1"; shift
2019-10-10 10:41:13 +04:00
local url repourl desc payload result
local -a vars
if [ -n "$user" -a "$user" != "$gogs_user" ]; then
2019-12-05 11:56:34 +04:00
# créer un dépôt dans une organisation
url="$gogs_url/api/v1/org/$user/repos"
2019-10-10 10:41:13 +04:00
repourl="$gogs_url/$user/$path"
else
2019-12-05 11:56:34 +04:00
# créer un dépôt pour un utilisateur
url="$gogs_url/api/v1/user/repos"
2019-10-10 10:41:13 +04:00
repourl="$gogs_url/$gogs_user/$path"
fi
vars=(name="$path" private=true)
[ -n "$1" ] && vars+=(description="$1"); shift
setx payload=json_build "${vars[@]}"
[ $# -gt 0 ] && vars=("$@") || vars=("")
setx result=curlto "$url" "$payload" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de création du dépôt
url: $url
payload: $payload
result: $result"
2019-10-10 10:41:13 +04:00
isatty && estep "Création du dépôt $repourl"
echo "$result" | json_get "${vars[@]}"
2020-09-08 11:51:40 +04:00
if [ -n "$update_origin" ]; then
2020-09-10 11:15:40 +04:00
_update_origin
_update_origin_push
2020-09-08 11:51:40 +04:00
fi
}
################################################################################
function list_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_list_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_list_action() {
local url result
local -a vars
if [ -n "$user" -a "$user" != "$gogs_user" ]; then
# lister les dépôts d'une organisation
url="$gogs_url/api/v1/orgs/$user/repos"
else
# lister les dépôts accessibles par l'utilisateur
url="$gogs_url/api/v1/user/repos"
fi
2019-10-10 10:41:13 +04:00
[ $# -gt 0 ] && vars=("$@") || vars=(full_name)
setx result=curlto "$url" "" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de listage des dépôts
url: $url
result: $result"
echo "$result" | json_each "${vars[@]}"
}
################################################################################
2019-10-10 10:24:07 +04:00
function get_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_get_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_get_action() {
2019-10-10 10:41:13 +04:00
local url repourl payload result
2019-10-10 10:24:07 +04:00
local -a vars
url="$gogs_url/api/v1/repos/$user/$path"
2019-10-10 10:41:13 +04:00
repourl="$gogs_url/$user/$path"
2019-10-10 10:24:07 +04:00
[ $# -gt 0 ] && vars=("$@") || vars=("")
local HTTP_METHOD=GET
2019-12-05 11:56:34 +04:00
setx result=curlto "$url" "" "" \
2019-10-10 10:24:07 +04:00
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de déplacement du dépôt
url: $url
payload: $payload
result: $result"
2019-10-10 10:41:13 +04:00
isatty && estep "Attributs du dépôt $repourl"
2019-10-10 10:24:07 +04:00
echo "$result" | json_get "${vars[@]}"
}
################################################################################
2019-10-08 23:07:55 +04:00
function edit_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
2019-10-08 23:07:55 +04:00
gogs_edit_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
2019-10-08 23:07:55 +04:00
function gogs_edit_action() {
2019-10-10 10:41:13 +04:00
local url repourl payload result
local -a vars
url="$gogs_url/api/v1/repos/$user/$path"
2019-10-10 10:41:13 +04:00
repourl="$gogs_url/$user/$path"
2019-12-05 11:56:34 +04:00
vars=()
2019-10-08 23:07:55 +04:00
while [[ "$1" == *=* ]]; do
2019-10-10 10:24:07 +04:00
vars+=("$1")
2019-10-08 23:07:55 +04:00
shift
done
setx payload=json_build "${vars[@]}"
[ $# -gt 0 ] && vars=("$@") || vars=("")
2019-10-08 23:07:55 +04:00
local HTTP_METHOD=PATCH
setx result=curlto "$url" "$payload" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de déplacement du dépôt
url: $url
payload: $payload
result: $result"
2019-10-10 10:41:13 +04:00
isatty && estep "Mise à jour du dépôt $repourl"
echo "$result" | json_get "${vars[@]}"
}
################################################################################
function delete_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_delete_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_delete_action() {
2019-10-10 10:41:13 +04:00
local url repourl payload result
url="$gogs_url/api/v1/repos/$user/$path"
2019-10-10 10:41:13 +04:00
repourl="$gogs_url/$user/$path"
local HTTP_METHOD=DELETE
2019-12-05 11:56:34 +04:00
setx result=curlto "$url" "" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de suppression du dépôt
url: $url
payload: $payload
result: $result"
2019-10-10 10:41:13 +04:00
isatty && estep "Suppression du dépôt $repourl"
[ -n "$result" ] && echo "$result"
return 0
}
################################################################################
2019-08-25 23:31:25 +04:00
action=
2020-09-08 11:51:40 +04:00
update_origin=
2019-08-25 23:31:25 +04:00
args=(
--help '$exit_with display_help'
-c,--create action=create
2020-09-10 11:15:40 +04:00
-u,--update,--update-origin update_origin=1
2019-08-25 23:31:25 +04:00
-l,--list action=list
2019-10-10 10:24:07 +04:00
-g,--get action=get
-e,--edit action=edit
2019-08-25 23:31:25 +04:00
-d,--delete action=delete
)
parse_args "$@"; set -- "${args[@]}"
2020-09-10 11:15:40 +04:00
if [ -z "$action" -a -n "$update_origin" ]; then
2020-11-27 10:19:14 +04:00
case "$1" in
c|create) action=create; shift;;
*) action=update-origin;;
esac
2020-09-10 11:15:40 +04:00
fi
2019-08-25 23:31:25 +04:00
if [ -z "$action" ]; then
action="$1"; shift
fi
[ -n "$action" ] || action=list
repoctl_init "$1"; shift
[ -n "$repourl" ] || die "Vous devez spécifier l'url du dépôt"
2019-08-25 23:31:25 +04:00
case "$action" in
2020-09-10 11:15:40 +04:00
u|update|update-origin) update_origin_action "$@";;
2020-09-08 11:51:40 +04:00
c|create) create_action "$update_origin" "$@";;
l|list) list_action "$@";;
2019-10-10 10:24:07 +04:00
g|get|s|show) get_action "$@";;
2019-10-08 23:07:55 +04:00
e|edit) edit_action "$@";;
d|del|delete|rm|remove) delete_action "$@";;
2019-08-25 23:31:25 +04:00
esac