390 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			390 lines
		
	
	
		
			11 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/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
 |