Álex Fog
Álex Fog

Reputation: 84

Batch file executed in shell script not waiting for user input

I've stumbled upon git-hooks and been trying to create one to run on Windows. So I've decided upon using batch files to do so because it seemed easy enough.

First, I renamed the pre-commit sample to pre-commit and called my bat steps there:

#!/bin/sh
$(pwd)/git-hooks/hooks/unit_test.bat &&
$(pwd)/git-hooks/hooks/integration_test.bat

The unit_test.bat only shows some messages and runs the unit tests task, but the integration_test.bat prompts the user on if they want to run these tests or not because they are generally slower.

The problem is that the prompt (done with either 'choice' or 'set /p') doesn't get the user input:

I've tried adding start to call the .bat files but it opens them on another cmd so it makes it impossible to stop the commit.

Files referenced

Upvotes: 0

Views: 793

Answers (2)

Álex Fog
Álex Fog

Reputation: 84

The freeze error was due to the fact that git-hooks disable interactivity, as @AnthonySotille pointed out.

I bypassed that situation by extracting the prompt to another .bat file and calling them with start /wait. That opens another cmd, runs the prompt, and exits using the success code to represent Y and the failure code as N. It doesn't seem like a good practice, but for now, it does the job.

This question might be considered a duplicate of How do I prompt the user from within a commit-msg hook?

Upvotes: 0

Compo
Compo

Reputation: 38589

I thought that gradlew was actually another batch file, gradlew.bat, so I'd assume, if you want it to return to the script upon completion you should use the Call command. Also, you should be aware that & concatenates two individual commands on one line, whereas && runs one command only when the previous one was successful. In your case, the Echo commands cannot be unsuccessful, so just & is necessary. Additionally, If ErrorLevel 1 menas if the error code was 1 or higher, which means, in your posted code, the code will always goto sim. What you should use instead is If Not ErrorLevel 2, If %ErrorLevel% Equ 1, or If "%ErrorLevel%" == "1".

Examples: (Please insert the full path to gradlew.bat instead of relying on easily corrupted or affected %Path% variable, and doublequote the path and executable name if it contains spaces or problematic characters). I have removed the unnecessary concatenation in the lower examples, as it is not required within a script.

unit_test.bat

@Echo Off
Echo ^> Testes unitários
Call gradlew.bat testReport || (Echo(& Echo Testes unitários falharam! Acesse o relatório de testes para conferir.& Exit 1)

integration_test.bat

@Echo Off
Echo(
Echo ^> Testes integrados
%SystemRoot%\System32\choice.exe /C sn /M "Esses testes geralmente são mais lentos. Quer rodar os testes integrados"
If Not ErrorLevel 2 GoTo sim
Echo(
Echo Não se esqueça de confirmar que os testes integrados passam antes de fazer o 'git push'!
Exit /B

:sim
Call gradlew.bat integrationTests || (
    Echo(
    Echo Testes integrados falharam! Acesse o relatório de testes para conferir.
)
Exit 1

or:

@Echo Off
Echo(
Echo ^> Testes integrados
%SystemRoot%\System32\choice.exe /C sn /M "Esses testes geralmente são mais lentos. Quer rodar os testes integrados"
If ErrorLevel 2 GoTo nao
Call gradlew.bat integrationTests || (
    Echo(
    Echo Testes integrados falharam! Acesse o relatório de testes para conferir.
)
Exit 1

:nao
Echo(
Echo Não se esqueça de confirmar que os testes integrados passam antes de fazer o 'git push'!
Exit /B

I would also suggest, based upon some of the characters you are using, that you ensure that the script is run using an appropriate codepage, (possibly 1252).

Upvotes: 2

Related Questions