From cdf090661456f3650fd4dc5df296fef9abd0a8f7 Mon Sep 17 00:00:00 2001 From: Michael Kessler Date: Tue, 4 Oct 2011 09:04:50 +0200 Subject: [PATCH] Move the DSL describing logic from the CLI to the DSLDescriber. --- lib/guard/cli.rb | 67 +--------------------- lib/guard/dsl_describer.rb | 96 +++++++++++++++++++++++++++++++- spec/guard/dsl_describer_spec.rb | 82 ++++++++++++++++++--------- 3 files changed, 153 insertions(+), 92 deletions(-) diff --git a/lib/guard/cli.rb b/lib/guard/cli.rb index 91e3e80..13a9a0e 100644 --- a/lib/guard/cli.rb +++ b/lib/guard/cli.rb @@ -50,7 +50,7 @@ module Guard :type => :boolean, :default => false, :aliases => '-A', - :banner => "Watch for all file modifications including moves and deletions" + :banner => 'Watch for all file modifications including moves and deletions' # Start Guard by initialize the defined Guards and watch the file system. # This is the default task, so calling `guard` is the same as calling `guard start`. @@ -66,37 +66,8 @@ module Guard # List the Guards that are available for use in your system and marks # those that are currently used in your `Guardfile`. # - # @example Guard list output - # - # Available guards: - # bundler * - # livereload - # ronn - # rspec * - # spork - # - # See also https://github.com/guard/guard/wiki/List-of-available-Guards - # * denotes ones already in your Guardfile - # - # @see Guard::DslDescriber - # def list - Guard::DslDescriber.evaluate_guardfile(options) - - installed = Guard::DslDescriber.guardfile_structure.inject([]) do |installed, group| - group[:guards].each { |guard| installed << guard[:name] } if group[:guards] - installed - end - - Guard::UI.info 'Available guards:' - - Guard::guard_gem_names.sort.uniq.each do |name| - Guard::UI.info " #{ name } #{ installed.include?(name) ? '*' : '' }" - end - - Guard::UI.info ' ' - Guard::UI.info 'See also https://github.com/guard/guard/wiki/List-of-available-Guards' - Guard::UI.info '* denotes ones already in your Guardfile' + Guard::DslDescriber.list(options) end desc 'version', 'Show the Guard version' @@ -138,40 +109,8 @@ module Guard # Shows all Guards and their options that are defined in # the `Guardfile`. # - # @example guard show output - # - # (global): - # bundler - # coffeescript: input => "app/assets/javascripts", noop => true - # jasmine - # rspec: cli => "--fail-fast --format Fuubar - # - # @see Guard::DslDescriber - # def show - Guard::DslDescriber.evaluate_guardfile(options) - - Guard::DslDescriber.guardfile_structure.each do |group| - unless group[:guards].empty? - if group[:group] - Guard::UI.info "Group #{ group[:group] }:" - else - Guard::UI.info '(global):' - end - - group[:guards].each do |guard| - line = " #{ guard[:name] }" - - unless guard[:options].empty? - line += ": #{ guard[:options].collect { |k, v| "#{ k } => #{ v.inspect }" }.join(', ') }" - end - - Guard::UI.info line - end - end - end - - Guard::UI.info '' + Guard::DslDescriber.show(options) end end diff --git a/lib/guard/dsl_describer.rb b/lib/guard/dsl_describer.rb index b5d7a77..e8fa981 100644 --- a/lib/guard/dsl_describer.rb +++ b/lib/guard/dsl_describer.rb @@ -2,6 +2,8 @@ require 'guard/dsl' module Guard + autoload :UI, 'guard/ui' + # The DslDescriber overrides methods to create an internal structure # of the Guardfile that is used in some inspection utility methods # like the CLI commands `show` and `list`. @@ -11,10 +13,97 @@ module Guard # class DslDescriber < Dsl - @@guardfile_structure = [ { :guards => [] } ] - class << self + # Evaluate the DSL methods in the `Guardfile`. + # + # @option options [Array] groups the groups to evaluate + # @option options [String] guardfile the path to a valid Guardfile + # @option options [String] guardfile_contents a string representing the content of a valid Guardfile + # @raise [ArgumentError] when options are not a Hash + # + def evaluate_guardfile(options = {}) + @@guardfile_structure = [{ :guards => [] }] + super options + end + + # List the Guards that are available for use in your system and marks + # those that are currently used in your `Guardfile`. + # + # @example Guard list output + # + # Available guards: + # bundler * + # livereload + # ronn + # rspec * + # spork + # + # See also https://github.com/guard/guard/wiki/List-of-available-Guards + # * denotes ones already in your Guardfile + # + # @param [Hash] options the Guard options + # + def list(options) + evaluate_guardfile(options) + + installed = guardfile_structure.inject([]) do |installed, group| + group[:guards].each { |guard| installed << guard[:name] } if group[:guards] + installed + end + + UI.info 'Available guards:' + + ::Guard.guard_gem_names.sort.uniq.each do |name| + UI.info " #{ name }#{ installed.include?(name) ? '*' : '' }" + end + + UI.info '' + UI.info 'See also https://github.com/guard/guard/wiki/List-of-available-Guards' + UI.info '* denotes ones already in your Guardfile' + end + + # Shows all Guards and their options that are defined in + # the `Guardfile`. + # + # @example guard show output + # + # (global): + # bundler + # coffeescript: input => "app/assets/javascripts", noop => true + # jasmine + # rspec: cli => "--fail-fast --format Fuubar + # + # @param [Hash] options the Guard options + # + def show(options) + evaluate_guardfile(options) + + guardfile_structure.each do |group| + unless group[:guards].empty? + if group[:group] + UI.info "Group #{ group[:group] }:" + else + UI.info '(global):' + end + + group[:guards].each do |guard| + line = " #{ guard[:name] }" + + unless guard[:options].empty? + line += ": #{ guard[:options].collect { |k, v| "#{ k } => #{ v.inspect }" }.join(', ') }" + end + + UI.info line + end + end + end + + UI.info '' + end + + private + # Get the Guardfile structure. # # @return [Array] the structure @@ -22,6 +111,7 @@ module Guard def guardfile_structure @@guardfile_structure end + end private @@ -50,7 +140,7 @@ module Guard # # @see Guard::Dsl#guard # - def guard(name, options = {}) + def guard(name, options = { }) node = (@group ? @@guardfile_structure.last : @@guardfile_structure.first) node[:guards] << { :name => name, :options => options } diff --git a/spec/guard/dsl_describer_spec.rb b/spec/guard/dsl_describer_spec.rb index 9c17ac6..7158b6c 100644 --- a/spec/guard/dsl_describer_spec.rb +++ b/spec/guard/dsl_describer_spec.rb @@ -1,38 +1,70 @@ require 'spec_helper' describe Guard::DslDescriber do - before(:each) do - ::Guard.stub!(:guards).and_return([mock('Guard')]) - user_config_path = File.expand_path(File.join('~', '.guard.rb')) - File.stub(:exist?).with(user_config_path) { false } + + let(:describer) { ::Guard::DslDescriber } + + let(:guardfile) do + <<-GUARD + guard 'test', :a => :b do + watch('c') + end + + group :a do + guard 'test', :x => 1, :y => 2, :z => 3 do + watch('c') + end + end + + group "b" do + guard 'another' do + watch('c') + end + end + GUARD end - it 'should evaluate a Guardfile and create the right structure' do - mixed_guardfile_string = <<-GUARD -guard 'test', :a => :b do - watch('c') -end - -group :a do - guard 'test' do - watch('c') + before do + @output = '' + Guard::UI.stub(:info) { |msg| @output << msg + "\n" } end -end -group "b" do - guard 'another' do - watch('c') + after do + Guard::UI.unstub(:info) end -end -GUARD - described_class.evaluate_guardfile(:guardfile_contents => mixed_guardfile_string) + describe '.list' do + it 'lists the available Guards' do + Guard.stub(:guard_gem_names).and_return ['test', 'another', 'even', 'more'] + describer.list(:guardfile_contents => guardfile) + @output.should eql < [ { :name => 'test', :options => { :a => :b } } ] }, - { :group => :a, :guards => [ { :name => 'test', :options => {} } ] }, - { :group => :b, :guards => [ { :name => 'another', :options => {} } ] } - ] +See also https://github.com/guard/guard/wiki/List-of-available-Guards +* denotes ones already in your Guardfile +OUTPUT + end + end + + describe '.show' do + it 'shows the Guards and their options' do + describer.show(:guardfile_contents => guardfile) + @output.should eql < :b +Group a: + test: x => 1, y => 2, z => 3 +Group b: + another + +OUTPUT + end end end