Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e4f5b4a

Browse files
author
Mike Foley
committedSep 28, 2015
Allow execution from scripts and GUI clients
If the Git hook is called from outside of a terminal, just fail on errors without trying to ask the user for input. This previously crashed because it assumed `/dev/tty` was present. This isn't the case when called from a GUI like RubyMine. Fixes #20
1 parent a2a8ae1 commit e4f5b4a

File tree

3 files changed

+54
-25
lines changed

3 files changed

+54
-25
lines changed
 

Diff for: ‎lib/fit_commit/runner.rb

+16-8
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,30 @@ def run
2222
run_validators
2323
return EXIT_CODE_ALLOW_COMMIT if [errors, warnings].all?(&:empty?)
2424
print_results
25+
allow_commit = errors.empty? || ask_force_commit
2526

26-
allow_commit = errors.empty?
27-
unless allow_commit
28-
stderr.print "\nForce commit? [y/n] "
29-
return EXIT_CODE_REJECT_COMMIT unless stdin.gets =~ /y/i
30-
allow_commit = true
27+
if allow_commit
28+
stderr.print "\n"
29+
EXIT_CODE_ALLOW_COMMIT
30+
else
31+
EXIT_CODE_REJECT_COMMIT
3132
end
32-
33-
stderr.print "\n"
34-
allow_commit ? EXIT_CODE_ALLOW_COMMIT : EXIT_CODE_REJECT_COMMIT
3533
rescue Interrupt # Ctrl-c
3634
EXIT_CODE_REJECT_COMMIT
3735
end
3836

3937
private
4038

39+
def ask_force_commit
40+
return unless interactive?
41+
stderr.print "\nForce commit? [y/n] "
42+
stdin.gets =~ /y/i
43+
end
44+
45+
def interactive?
46+
stdin.tty?
47+
end
48+
4149
def run_validators
4250
validators.each do |validator|
4351
validator.validate(lines)

Diff for: ‎templates/hooks/commit-msg

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
11
#!/usr/bin/env sh
2-
#
3-
# This hook will attempt to setup your environment before running checks.
4-
5-
if which rvm > /dev/null 2>&1
6-
then cmd="rvm default do ruby"
7-
elif which rbenv > /dev/null 2>&1
8-
then cmd="rbenv exec ruby"
9-
else cmd="ruby"
10-
fi
112

123
export COMMIT_MESSAGE_PATH=$1
134
if [ -z "$COMMIT_MESSAGE_PATH" ]; then
@@ -35,7 +26,19 @@ if [ -z "$GIT_BRANCH_NAME" ]; then
3526
exit 0
3627
fi
3728

38-
${cmd} -rrubygems -e '
29+
if which rvm > /dev/null 2>&1
30+
then cmd="rvm default do ruby"
31+
elif which rbenv > /dev/null 2>&1
32+
then cmd="rbenv exec ruby"
33+
else cmd="ruby"
34+
fi
35+
36+
# allow user input if running in a terminal
37+
if [ -t 1 ]; then
38+
exec < /dev/tty
39+
fi
40+
41+
$cmd -rrubygems -e '
3942
begin
4043
require "fit_commit"
4144
true
@@ -46,4 +49,4 @@ fit-commit: Did you set your Ruby version?
4649
MESSAGE
4750
false
4851
end and FitCommit.run
49-
' < /dev/tty
52+
'

Diff for: ‎test/unit/runner_test.rb

+24-6
Original file line numberDiff line numberDiff line change
@@ -65,31 +65,49 @@ def call_runner
6565
describe "commit msg contains errors" do
6666
let(:commit_msg) { "foo.\nbar" }
6767

68-
def assert_error_output
68+
def assert_error_output(interactive: true)
6969
stderr_lines = stderr.read.lines.map(&:chomp)
70-
assert_equal 8, stderr_lines.size
70+
expected_lines = interactive ? 8 : 6
71+
assert_equal expected_lines, stderr_lines.size
7172
assert_equal commit_msg, stderr_lines[0..1].join("\n")
7273
assert_empty stderr_lines[2]
7374
assert_match(/\A1: Error: /, stderr_lines[3])
7475
assert_match(/\A1: Error: /, stderr_lines[4])
7576
assert_match(/\A2: Error: /, stderr_lines[5])
76-
assert_empty stderr_lines[6]
77-
assert_equal "Force commit? [y/n] ", stderr_lines[7]
77+
if interactive
78+
assert_empty stderr_lines[6]
79+
assert_equal "Force commit? [y/n] ", stderr_lines[7]
80+
end
81+
end
82+
83+
def fake_tty(text)
84+
StringIO.new(text).tap do |stringio|
85+
def stringio.tty?
86+
true
87+
end
88+
end
7889
end
7990

8091
describe "user does not force commit" do
81-
let(:stdin) { StringIO.new("n") }
92+
let(:stdin) { fake_tty("n") }
8293
it "prints errors to stderr and rejects commit" do
8394
assert_equal FitCommit::Runner::EXIT_CODE_REJECT_COMMIT, call_runner
8495
assert_error_output
8596
end
8697
end
8798
describe "user forces commit" do
88-
let(:stdin) { StringIO.new("y") }
99+
let(:stdin) { fake_tty("y") }
89100
it "prints errors to stderr and allows commit" do
90101
assert_equal FitCommit::Runner::EXIT_CODE_ALLOW_COMMIT, call_runner
91102
assert_error_output
92103
end
93104
end
105+
describe "TTY not available" do
106+
let(:stdin) { StringIO.new("") }
107+
it "prints errors to stderr and rejects commit" do
108+
assert_equal FitCommit::Runner::EXIT_CODE_REJECT_COMMIT, call_runner
109+
assert_error_output(interactive: false)
110+
end
111+
end
94112
end
95113
end

0 commit comments

Comments
 (0)
Please sign in to comment.