323 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
 | 
						|
urequire DEFAULTS json
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: piloter un serveur git (gitolite, gogs, gitea, etc.)
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname ACTION URL [options]
 | 
						|
 | 
						|
ACTIONS
 | 
						|
    create URL [description]
 | 
						|
        Créer un nouveau dépôt avec la description spécifiée
 | 
						|
 | 
						|
    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
 | 
						|
 | 
						|
    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.
 | 
						|
 | 
						|
    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
 | 
						|
 | 
						|
    delete URL
 | 
						|
        Supprimer le dépôt spécifié"
 | 
						|
}
 | 
						|
 | 
						|
function repoctl_init() {
 | 
						|
    repourl="${1%.git}"
 | 
						|
    [ -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 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 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[@]}"
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
 | 
						|
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=
 | 
						|
args=(
 | 
						|
    --help '$exit_with display_help'
 | 
						|
    -c,--create action=create
 | 
						|
    -l,--list action=list
 | 
						|
    -g,--get action=get
 | 
						|
    -e,--edit action=edit
 | 
						|
    -d,--delete action=delete
 | 
						|
)
 | 
						|
parse_args "$@"; set -- "${args[@]}"
 | 
						|
 | 
						|
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
 | 
						|
c|create) create_action "$@";;
 | 
						|
l|list) list_action "$@";;
 | 
						|
g|get|s|show) get_action "$@";;
 | 
						|
e|edit) edit_action "$@";;
 | 
						|
d|del|delete|rm|remove) delete_action "$@";;
 | 
						|
esac
 |