commit-msg hook 내에서 사용자에게 어떻게 프롬프트합니까?
커밋 메시지가 특정 지침을 따르지 않으면 사용자에게 경고하고 커밋 메시지를 편집하거나 경고를 무시하거나 커밋을 취소 할 수있는 옵션을 제공하고 싶습니다. 문제는 내가 stdin에 액세스 할 수없는 것 같다는 것입니다.
아래는 내 commit-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
범위 정보를 비워두면 다음과 같은 결과가 나타납니다.
Scope information should not be omitted
Do you want to:
1) edit the commit message 3) cancel the commit
2) ignore this warning
#?
메시지는 정확하지만 실제로 입력을 위해 멈추지는 않습니다. 또한 더 간단한 "읽기"명령을 사용해 보았지만 동일한 문제가 있습니다. 문제는이 시점에서 git이 stdin을 제어하고 자체 입력을 제공한다는 것입니다. 이 문제를 어떻게 해결합니까?
업데이트 : 이것은 불행히도 내가 운이 없다는 것을 암시하는 이 질문 의 중복 일 수 있습니다 .
호출 exec < /dev/tty
은 키보드에 표준 입력을 할당합니다. 커밋 후 자식 후크에서 나를 위해 작동합니다.
#!/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
commit-msg
(당신이 발견 한 것처럼) 후크는 대화 형 환경에서 실행되지 않습니다.
사용자에게 신뢰할 수있는 알림을 제공하는 유일한 방법은 stdout에 오류를 작성하고 커밋 메시지의 복사본을 BAD_MSG
파일에 배치하고 사용자에게 파일을 편집하도록 지시하는 것입니다.git commit --file=BAD_MSG
환경을 제어 할 수있는 경우 제안 된 메시지를 확인하는 래퍼 스크립트 인 대체 편집기를 사용할 수 있으며 추가 주석 메시지로 편집기를 다시 시작할 수 있습니다.
기본적으로 편집기를 실행하고 저장된 파일을 규칙에 따라 확인합니다. 실패하면 #
파일 앞에 경고 메시지 (앞에)를 추가 하고 편집기를 다시 시작하십시오.
#FORCE=true
체크를 억제하고 계속하는 메시지에 라인 을 넣도록 허용 할 수도 있습니다 .
하려면 select
입력을위한 정지, 당신은 또한 리디렉션을 시도 할 수 stdin
의 select
에서 /dev/fd/3
(: 참조 잠시 루프 내에서 bash는 읽기 입력 ).
# 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
이것은 명령 줄에서 git commit을 실행할 때 잘 작동합니다. Windows (리눅스에서 시도하지 않음)에서 gitk 또는 git-gui를 사용하면 "exec </ dev / tty"줄에 오류가 발생하기 때문에 메시지를 표시 할 수 없습니다.
해결책은 후크에서 git-bash.exe를 호출하는 것입니다.
.git / hooks / post-commit에는 다음이 포함됩니다.
#!/bin/sh
exec /c/Program\ Files/Git/git-bash.exe /path/to/my_repo/.git/hooks/post-checkout.sh
.git / hooks / post-commit.sh 파일에는 다음이 포함됩니다.
# --------------------------------------------------------
# usage: f_askContinue "my question ?"
function f_askContinue {
local myQuestion=$1
while true; do
read -p "${myQuestion} " -n 1 -r answer
case $answer in
[Yy]* ) printf "\nOK\n"; break;;
[Nn]* ) printf "\nAbandon\n";
exit;;
* ) printf "\nAnswer with Yes or No.\n";;
esac
done
}
f_askContinue "Do you want to continue ?"
echo "This command is executed after the prompt !"
Node.js 또는 TypeScript에서 수행하는 방법
편집 : npm 패키지를 만들었습니다.
I see people commenting on how to do it for other languages in Eliot Sykes answer, but the JavaScript solution is a bit long so I'll make a separate answer.
I'm not sure if O_NOCTTY
is required, but it doesn't seem to affect anything. I don't really understand what a controlling terminal is. GNU docs description. I think what it means is that with O_NOCTTY
on, you wouldn't be able to send a CTRL+C
to the process (if it doesn't already have a controlling terminal). In that case, I'll leave it on so you don't control spawned processes. The main node process should already have a controlling terminal, I think.
I adapted the answer from this GitHub issue
I don't see any docs on how to use the tty.ReadStream
constructor so I did a bit of trial and error / digging through Node.js source code.
You have to use Object.defineProperty
because Node.js internals uses it too, and doesn't define a setter. An alternative is to do process.stdin.fd = fd
, but I get duplicate output that way.
Anyway, I wanted to use this with Husky.js and it seems to work so far. I should probably turn this into an npm package when I get the time.
Node.js
#!/usr/bin/env node
const fs = require('fs');
const tty = require('tty');
if (!process.stdin.isTTY) {
const { O_RDONLY, O_NOCTTY } = fs.constants;
let fd;
try {
fd = fs.openSync('/dev/tty', O_RDONLY + O_NOCTTY);
} catch (error) {
console.error('Please push your code in a terminal.');
process.exit(1);
}
const stdin = new tty.ReadStream(fd);
Object.defineProperty(process, 'stdin', {
configurable: true,
enumerable: true,
get: () => stdin,
});
}
...Do your stuff...
process.stdin.destroy();
process.exit(0);
TypeScript:
#!/usr/bin/env ts-node
import fs from 'fs';
import tty from 'tty';
if (!process.stdin.isTTY) {
const { O_RDONLY, O_NOCTTY } = fs.constants;
let fd;
try {
fd = fs.openSync('/dev/tty', O_RDONLY + O_NOCTTY);
} catch (error) {
console.error('Please push your code in a terminal.');
process.exit(1);
}
// @ts-ignore: `ReadStream` in @types/node incorrectly expects an object.
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37174
const stdin = new tty.ReadStream(fd);
Object.defineProperty(process, 'stdin', {
configurable: true,
enumerable: true,
get: () => stdin,
});
}
...Do your stuff...
process.stdin.destroy();
process.exit(0);
read -p "Question? [y|n] " -n 1 -r < /dev/tty
echo
if echo $REPLY | grep -E '^[Yy]$' > /dev/null; then
#do if Yes
else
#do if No
fi
참고URL : https://stackoverflow.com/questions/3417896/how-do-i-prompt-the-user-from-within-a-commit-msg-hook
'Program Tip' 카테고리의 다른 글
Ruby on Rails의 모델 내에서 current_user에 액세스 (0) | 2020.11.07 |
---|---|
Ruby on Rails의 form_for에서 hidden_field를 어떻게 사용하나요? (0) | 2020.11.07 |
PHP 5.4- '$ this 지원 종료' (0) | 2020.11.07 |
Android BLE API : GATT 알림이 수신되지 않음 (0) | 2020.11.07 |
Firefox가 메타 태그로 새로 고침시 입력 값을 기억하지 못하도록 방지 (0) | 2020.11.07 |