77 votes

Comment inviter l'utilisateur à partir d'un hook commit-msg?

Je tiens à avertir l'utilisateur si leur message de commit ne suit pas un certain ensemble de lignes directrices, et ensuite leur donner la possibilité de modifier leur message de commit, ignorer l'avertissement, ou d'annuler la livraison. Le problème est que je ne semble pas avoir d'accès à l'entrée standard.

Ci-dessous est mon commit-fichier msg:

function verify_info {
    if [ -z "$(grep '$2:.*[a-zA-Z]' $1)" ]
    then
        echo >&2 $2 information should not be omitted
        local_editor=`git config --get core.editor`
        if [ -z "${local_editor}" ]
        then
            local_editor=${EDITOR}
        fi
        echo "Do you want to"
        select CHOICE in "edit the commit message" "ignore this warning" "cancel the commit"; do
            case ${CHOICE} in
                i*) echo "Warning ignored"
                    ;;
                e*) ${local_editor} $1
                    verify_info "$1" $2
                    ;;
                *)  echo "CHOICE = ${CHOICE}"
                    exit 1
                    ;;
            esac
        done
    fi
}

verify_info "$1" "Scope"
if [ $# -ne 0 ];
then
    exit $#
fi
verify_info "$1" "Affects"
if [ $# -ne 0 ];
then
    exit $#
fi

exit 0

Voici le résultat quand je quitte le Champ de l'information en blanc:

Scope information should not be omitted
Do you want to:
1) edit the commit message  3) cancel the commit
2) ignore this warning
#?

Le message est correct, mais il ne fait pas d'arrêt pour l'entrée. J'ai aussi essayé d'utiliser le plus simple "lecture" de commande, et il a le même problème. Il semble que le problème est qu'à ce stade, git a le contrôle de l'entrée standard stdin et fournit sa propre entrée. Comment puis-je résoudre ce problème?

Mise à jour: Il semble que ce pourrait être un doublon de cette question qui, malheureusement, semble suggérer que je suis hors de la chance.

165voto

Eliot Sykes Points 1174

L'appel exec < /dev/tty attribue une entrée standard au clavier. Fonctionne pour moi dans un hook git post-commit:

 #!/bin/sh

echo "[post-commit hook] Commit done!"

# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-commit hook] Check for outdated gems? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'
  fi
  case $yn in
      [Yy] ) bundle outdated --pre; break;;
      [Nn] ) exit;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done
 

6voto

Frosty Points 1624

Le commit-msg du crochet n'est pas exécuté dans un environnement interactif (comme vous l'avez remarqué).

La seule façon fiable de notifier à l'utilisateur serait d'écrire une erreur sur la sortie standard, placez une copie du message de commit dans un "BAD_MSG fichier et demander à l'utilisateur de modifier le fichier et "git commit --file=BAD_MSG'


Si vous avez un certain contrôle sur l'environnement, vous pourriez avoir un autre éditeur, qui est un script qui vérifie le message proposé, et peut redémarrer l'éditeur, avec un supplément commenté message.

Fondamentalement, vous exécutez l'éditeur, vérifiez le fichier enregistré à l'encontre de vos règles. et si elle échoue, précédez votre message d'avertissement (avec des #) pour le fichier et redémarrez l'éditeur.

On pourrait même leur permettre de mettre dans un "#FORCE=true' de ligne dans le message qui serait de supprimer la vérification et de continuer.

1voto

perx Points 11

Pour que select s’arrête pour une entrée, vous pouvez également essayer de rediriger les stdin de select de /dev/fd/3 (voir: lire l’entrée dans bash dans une boucle while ).

 # sample code using a while loop to simulate git consuming stdin
{ 
echo 'fd 0' | while read -r stdin; do
   echo "stdin: $stdin"
   echo "Do you want to"
   select CHOICE in "edit the commit message" "ignore this warning" "cancel the commit"; do
      case ${CHOICE} in
         i*) echo "Warning ignored"
             ;;
         e*) echo ${local_editor} $1
             echo verify_info "$1" $2
             ;;
         *)  echo "CHOICE = ${CHOICE}"
             exit 1
             ;;
      esac
   done 0<&3 3<&-
done
} 3<&- 3<&0
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X