#!/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 function display_help() { uecho "$scriptname: piloter un serveur git (gitolite, gogs, gitea, etc.) USAGE $scriptname ACTION URL [options] ACTIONS u|update-origin URL Mettre à jour origin dans le dépôt courant avec l'url spécifié c|create URL [description] Créer un nouveau dépôt avec la description spécifiée 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 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 g|get URL [VARs...] 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. e|edit URL var=value... 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 d|delete URL Supprimer le dépôt spécifié" } function repoctl_init() { repourl="$1" [ -n "$repourl" ] || return rname= rtype=gitolite rprefix= REPO_PREFIXES=() REPO_TYPES=() set_defaults repoctl # 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") 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 } ################################################################################ function _update_origin() { estep "Mise à jour de l'origine" git remote set-url origin "${repourl%.git}.git" } 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() { local update_origin="$1"; shift local url repourl desc payload result local -a vars if [ -n "$user" -a "$user" != "$gogs_user" ]; then # créer un dépôt dans une organisation url="$gogs_url/api/v1/org/$user/repos" repourl="$gogs_url/$user/$path" else # créer un dépôt pour un utilisateur url="$gogs_url/api/v1/user/repos" 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" isatty && estep "Création du dépôt $repourl" echo "$result" | json_get "${vars[@]}" if [ -n "$update_origin" ]; then _update_origin _update_origin_push 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 [ $# -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[@]}" } ################################################################################ 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() { local url repourl payload result local -a vars url="$gogs_url/api/v1/repos/$user/$path" repourl="$gogs_url/$user/$path" [ $# -gt 0 ] && vars=("$@") || vars=("") local HTTP_METHOD=GET 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 déplacement du dépôt url: $url payload: $payload result: $result" isatty && estep "Attributs du dépôt $repourl" echo "$result" | json_get "${vars[@]}" } ################################################################################ function edit_action() { case "$rtype" in #gitolite) ;; gogs|gitea) gogs_setvars gogs_edit_action "$@" ;; *) die "$rtype: type de dépôt non supporté";; esac } function gogs_edit_action() { local url repourl payload result local -a vars url="$gogs_url/api/v1/repos/$user/$path" repourl="$gogs_url/$user/$path" vars=() while [[ "$1" == *=* ]]; do vars+=("$1") shift done setx payload=json_build "${vars[@]}" [ $# -gt 0 ] && vars=("$@") || vars=("") 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" 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() { local url repourl payload result url="$gogs_url/api/v1/repos/$user/$path" repourl="$gogs_url/$user/$path" local HTTP_METHOD=DELETE 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" isatty && estep "Suppression du dépôt $repourl" [ -n "$result" ] && echo "$result" return 0 } ################################################################################ action= update_origin= args=( --help '$exit_with display_help' -c,--create action=create -u,--update,--update-origin update_origin=1 -l,--list action=list -g,--get action=get -e,--edit action=edit -d,--delete action=delete ) parse_args "$@"; set -- "${args[@]}" if [ -z "$action" -a -n "$update_origin" ]; then case "$1" in c|create) action=create; shift;; *) action=update-origin;; esac fi 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" case "$action" in u|update|update-origin) update_origin_action "$@";; c|create) create_action "$update_origin" "$@";; l|list) list_action "$@";; g|get|s|show) get_action "$@";; e|edit) edit_action "$@";; d|del|delete|rm|remove) delete_action "$@";; esac