From b439fd234c78c41b8e9c01608af031a335e33722 Mon Sep 17 00:00:00 2001 From: Tomasz Gieniusz Date: Fri, 19 Oct 2012 21:11:47 +0200 Subject: [PATCH] command observers --- lib/git_stats/cli.rb | 4 +-- lib/git_stats/generator.rb | 38 ++++++++++-------------- lib/git_stats/git_data/command_runner.rb | 4 +-- lib/git_stats/git_data/repo.rb | 22 ++++++++++++-- spec/cli_spec.rb | 2 +- spec/generator_spec.rb | 20 ++++++++++--- spec/repo_spec.rb | 28 +++++++++++++++++ 7 files changed, 84 insertions(+), 34 deletions(-) diff --git a/lib/git_stats/cli.rb b/lib/git_stats/cli.rb index ccca9a3fb..2452b7b30 100644 --- a/lib/git_stats/cli.rb +++ b/lib/git_stats/cli.rb @@ -7,8 +7,8 @@ class GitStats::CLI repo_path, out_path = args GitStats::Generator.new(repo_path, out_path) { |g| - g.git_command_observer { |command, result| puts "#{command}" } - }.generate + g.add_command_observer { |command, result| puts "#{command}" } + }.render_all end end diff --git a/lib/git_stats/generator.rb b/lib/git_stats/generator.rb index 338815c49..c9b0516eb 100644 --- a/lib/git_stats/generator.rb +++ b/lib/git_stats/generator.rb @@ -1,36 +1,30 @@ module GitStats class Generator + delegate :add_command_observer, to: :@repo + delegate :render_all, to: :@view + def initialize(repo_path, out_path) - @repo_path, @out_path = repo_path, out_path + validate_paths(repo_path, out_path) + + @repo = GitData::Repo.new(path: repo_path) + view_data = StatsView::ViewData.new(@repo) + @view = StatsView::View.new(view_data, out_path) + yield self if block_given? end - def git_command_observer(&block) - @git_command_observer = block - end - - def generate - validate_paths - - repo = GitData::Repo.new(path: @repo_path, git_command_observer: @git_command_observer) - view_data = StatsView::ViewData.new(repo) - - view = StatsView::View.new(view_data, @out_path) - view.render_all - end - private - def validate_paths - validate_repo_path - validate_out_path + def validate_paths(repo_path, out_path) + validate_repo_path(repo_path) + validate_out_path(out_path) end - def validate_repo_path - raise ArgumentError, "#@repo_path is not a git repository" unless Dir.exists?("#@repo_path/.git") + def validate_repo_path(repo_path) + raise ArgumentError, "#{repo_path} is not a git repository" unless Dir.exists?("#{repo_path}/.git") end - def validate_out_path - raise ArgumentError, "#@out_path is not a directory" unless Dir.exists?(@out_path) + def validate_out_path(out_path) + raise ArgumentError, "#{out_path} is not a directory" unless Dir.exists?(out_path) end end diff --git a/lib/git_stats/git_data/command_runner.rb b/lib/git_stats/git_data/command_runner.rb index 47f2693ce..9ff16c947 100644 --- a/lib/git_stats/git_data/command_runner.rb +++ b/lib/git_stats/git_data/command_runner.rb @@ -1,8 +1,8 @@ module GitStats module GitData class CommandRunner - def self.run(command) - %x[#{command}] + def run(path, command) + Dir.chdir(path) { %x[#{command}] } end end end diff --git a/lib/git_stats/git_data/repo.rb b/lib/git_stats/git_data/repo.rb index 049df3084..febd820a1 100644 --- a/lib/git_stats/git_data/repo.rb +++ b/lib/git_stats/git_data/repo.rb @@ -59,7 +59,9 @@ module GitStats end def run(command) - in_repo_dir { CommandRunner.run(command) } + result = command_runner.run(path, command) + invoke_command_observers(command, result) + result end def run_and_parse(command) @@ -67,12 +69,17 @@ module GitStats command_parser.parse(command, result) end + def command_runner + @command_runner ||= CommandRunner.new + end + def command_parser @command_parser ||= CommandParser.new end - def in_repo_dir - Dir.chdir(path) { yield } + def add_command_observer(proc=nil, &block) + command_observers << block if block_given? + command_observers << proc if proc end def to_s @@ -83,6 +90,15 @@ module GitStats self.path == other.path end + private + def command_observers + @command_observers ||= [] + end + + def invoke_command_observers(command, result) + command_observers.each { |o| o.call(command, result) } + end + end end end \ No newline at end of file diff --git a/spec/cli_spec.rb b/spec/cli_spec.rb index 79477447b..b7a3169ed 100644 --- a/spec/cli_spec.rb +++ b/spec/cli_spec.rb @@ -7,7 +7,7 @@ describe GitStats::CLI do it 'should invoke generator with console arguments given' do generator = double('generator') GitStats::Generator.should_receive(:new).with(repo_path, out_path).and_return(generator) - generator.should_receive(:generate) + generator.should_receive(:render_all) subject.start(repo_path, out_path) end diff --git a/spec/generator_spec.rb b/spec/generator_spec.rb index 9c34dfb61..a56566ab2 100644 --- a/spec/generator_spec.rb +++ b/spec/generator_spec.rb @@ -9,17 +9,29 @@ describe GitStats::Generator do it 'should raise exception if given repo path is not a git repository' do Dir.should_receive(:exists?).with("#{repo_path}/.git").and_return(false) - expect { generator.generate }.to raise_error(ArgumentError) + expect { generator }.to raise_error(ArgumentError) end it "should raise exception if given out directory doesn't exist" do Dir.should_receive(:exists?).with(out_path).and_return(false) - expect { generator.generate }.to raise_error(ArgumentError) + expect { generator }.to raise_error(ArgumentError) + end + + it 'should pass command observer to repo' do + repo = double('repo') + GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo) + + generator = GitStats::Generator.new(repo_path, out_path) + + observer = double('observer') + repo.should_receive(:add_command_observer).with(observer) + + generator.add_command_observer observer end it 'should render all templates with view data for this repo' do repo = double('repo') - GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, git_command_observer: nil).and_return(repo) + GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo) view_data = double('view_data') GitStats::StatsView::ViewData.should_receive(:new).with(repo).and_return(view_data) @@ -28,6 +40,6 @@ describe GitStats::Generator do GitStats::StatsView::View.should_receive(:new).with(view_data, out_path).and_return(view) view.should_receive(:render_all) - generator.generate + generator.render_all end end \ No newline at end of file diff --git a/spec/repo_spec.rb b/spec/repo_spec.rb index 2dc1903f5..c3b40ecf7 100644 --- a/spec/repo_spec.rb +++ b/spec/repo_spec.rb @@ -47,6 +47,34 @@ describe GitStats::GitData::Repo do end end + describe 'command observers' do + context 'should be invoked after every command' do + it 'should accept block' do + command_runner = double('command_runner') + repo = build(:repo, command_runner: command_runner) + + observer = double('observer') + repo.add_command_observer { |command, result| observer.invoked(command, result) } + command_runner.should_receive(:run).with(repo.path, 'aa').and_return('bb') + observer.should_receive(:invoked).with('aa', 'bb') + + repo.run('aa') + end + + it 'should accept Proc' do + command_runner = double('command_runner') + repo = build(:repo, command_runner: command_runner) + + observer = double('observer') + repo.add_command_observer(observer) + command_runner.should_receive(:run).with(repo.path, 'aa').and_return('bb') + observer.should_receive(:call).with('aa', 'bb') + + repo.run('aa') + end + end + end + describe 'git output parsing' do context 'invoking authors command' do before do