Skip to content

Commit 268a825

Browse files
committed
Require git repo location to be given
Whomever calls Hook::init should be responsible for saying where to install. We also simplify things a bit by relying on a tempdir in the tests.
1 parent d61ad70 commit 268a825

File tree

4 files changed

+42
-66
lines changed

4 files changed

+42
-66
lines changed

lib/git_tracker/hook.rb

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,33 @@
22

33
module GitTracker
44
class Hook
5-
attr_reader :hook_file
5+
BODY = <<~HOOK.freeze
6+
#!/usr/bin/env bash
67
7-
def self.init
8-
init_at(Repository.root)
9-
end
8+
if command -v git-tracker >/dev/null; then
9+
git-tracker prepare-commit-msg "$@"
10+
fi
11+
12+
HOOK
13+
14+
attr_reader :hook_file
1015

11-
def self.init_at(root)
12-
new(root).write
16+
def self.init(at:)
17+
new(at: at).write
1318
end
1419

15-
def initialize(root)
16-
@hook_file = File.join(root, ".git", "hooks", "prepare-commit-msg")
20+
def initialize(at:)
21+
@hook_file = Pathname(at).join(PREPARE_COMMIT_MSG_PATH)
1722
end
1823

1924
def write
20-
File.open(hook_file, "w") do |f|
21-
f.write(hook_body)
25+
hook_file.open("w") do |f|
26+
f.write(BODY)
2227
f.chmod(0o755)
2328
end
2429
end
2530

26-
private
27-
28-
def hook_body
29-
<<~HOOK
30-
#!/usr/bin/env bash
31-
32-
if command -v git-tracker >/dev/null; then
33-
git-tracker prepare-commit-msg "$@"
34-
fi
35-
36-
HOOK
37-
end
31+
PREPARE_COMMIT_MSG_PATH = ".git/hooks/prepare-commit-msg".freeze
32+
private_constant :PREPARE_COMMIT_MSG_PATH
3833
end
3934
end

lib/git_tracker/runner.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
require "git_tracker/prepare_commit_message"
22
require "git_tracker/hook"
3+
require "git_tracker/repository"
34
require "git_tracker/version"
45

56
module GitTracker
67
module Runner
78
def self.execute(cmd_arg = "help", *args)
89
command = cmd_arg.tr("-", "_")
10+
911
abort("[git_tracker] command: '#{cmd_arg}' does not exist.") unless respond_to?(command)
12+
1013
send(command, *args)
1114
end
1215

@@ -15,7 +18,7 @@ def self.prepare_commit_msg(*args)
1518
end
1619

1720
def self.init
18-
Hook.init
21+
Hook.init(at: Repository.root)
1922
end
2023

2124
def self.install

spec/git_tracker/hook_spec.rb

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,26 @@
11
require "git_tracker/hook"
2-
require "active_support/core_ext/string/strip"
32

43
RSpec.describe GitTracker::Hook do
5-
subject(:hook) { described_class }
6-
let(:root) { "/path/to/git/repo/toplevel" }
7-
let(:hook_path) { File.join(root, ".git", "hooks", "prepare-commit-msg") }
8-
9-
describe ".init" do
10-
before do
11-
allow(GitTracker::Repository).to receive(:root) { root }
12-
allow(hook).to receive(:init_at)
13-
end
14-
15-
it "initializes to the root of the Git repository" do
16-
hook.init
17-
expect(hook).to have_received(:init_at).with(root)
4+
subject(:hook) { described_class.new(at: Pathname(@repo_root_dir)) }
5+
6+
around do |example|
7+
Dir.mktmpdir do |dir|
8+
@repo_root_dir = dir
9+
hooks_dir = Pathname(dir).join(".git/hooks")
10+
FileUtils.mkdir_p(hooks_dir)
11+
example.call
1812
end
1913
end
2014

21-
describe ".init_at" do
22-
let(:fake_file) { GitTracker::FakeFile.new }
23-
before do
24-
allow(File).to receive(:open).and_yield(fake_file)
25-
end
26-
27-
it "writes the hook into the hooks directory" do
28-
hook.init_at(root)
29-
expect(File).to have_received(:open).with(hook_path, "w")
30-
end
15+
it "makes the hook executable" do
16+
hook.write
3117

32-
it "makes the hook executable" do
33-
hook.init_at(root)
34-
expect(fake_file.mode).to eq(0o755)
35-
end
36-
37-
it "writes the hook code in the hook file" do
38-
hook_code = <<-HOOK_CODE.strip_heredoc
39-
#!/usr/bin/env bash
40-
41-
if command -v git-tracker >/dev/null; then
42-
git-tracker prepare-commit-msg "$@"
43-
fi
18+
expect(hook.hook_file).to be_executable
19+
end
4420

45-
HOOK_CODE
21+
it "writes the hook code in the hook file" do
22+
hook.write
4623

47-
hook.init_at(root)
48-
expect(fake_file.content).to eq(hook_code)
49-
end
24+
expect(hook.hook_file.read).to eq(described_class::BODY)
5025
end
5126
end

spec/git_tracker/runner_spec.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
end
1313

1414
it "runs the hook, passing the args" do
15-
expect(runner).to receive(:prepare_commit_msg).with(*args) { true }
15+
expect(runner).to receive(:prepare_commit_msg).with(*args)
1616
runner.execute("prepare-commit-msg", *args)
1717
end
1818

@@ -26,14 +26,17 @@
2626

2727
describe ".prepare_commit_msg" do
2828
it "runs the hook, passing the args" do
29-
expect(GitTracker::PrepareCommitMessage).to receive(:run).with(*args) { true }
29+
expect(GitTracker::PrepareCommitMessage).to receive(:run).with(*args)
3030
runner.prepare_commit_msg(*args)
3131
end
3232
end
3333

3434
describe ".init" do
35+
let(:repo_root) { "/path/to/git/repo/root" }
36+
3537
it "tells the hook to initialize itself" do
36-
expect(GitTracker::Hook).to receive(:init)
38+
allow(GitTracker::Repository).to receive(:root) { repo_root }
39+
expect(GitTracker::Hook).to receive(:init).with(at: repo_root)
3740
runner.init
3841
end
3942
end

0 commit comments

Comments
 (0)