Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extract methods from #notifications.

  • Loading branch information...
commit bdf379a1fb0d929cfc9e3411170865224d7e1ab2 1 parent c2349a2
@acrmp acrmp authored
View
1  lib/foodcritic.rb
@@ -9,6 +9,7 @@
require_relative 'foodcritic/command_line'
require_relative 'foodcritic/domain'
require_relative 'foodcritic/error_checker'
+require_relative 'foodcritic/notifications'
require_relative 'foodcritic/api'
require_relative 'foodcritic/dsl'
require_relative 'foodcritic/linter'
View
56 lib/foodcritic/api.rb
@@ -6,6 +6,7 @@ module FoodCritic
module Api
include FoodCritic::Chef
+ include FoodCritic::Notifications
# Find attribute accesses by type.
#
@@ -188,61 +189,6 @@ def match(node)
:line => pos['line'].to_i, :column => pos['column'].to_i}
end
- # Decode resource notifications.
- #
- # @param [Nokogiri::XML::Node] ast The AST to check for notifications.
- # @return [Array] A flat array of notifications. The resource_name may be
- # a string or a Node if the resource name is an expression.
- def notifications(ast)
- return [] unless ast.respond_to?(:xpath)
- ast.xpath('descendant::command[ident/@value="notifies" or
- ident/@value="subscribes"]').map do |notifies|
-
- params = notifies.xpath('descendant::method_add_arg[fcall/ident/
- @value="resources"]/descendant::assoc_new')
- timing = notifies.xpath('args_add_block/args_add/symbol_literal[last()]/
- symbol/ident[1]/@value')
- if params.empty?
- target = notifies.xpath('args_add_block/args_add/
- descendant::tstring_content/@value').to_s
- match = target.match(/^([^\[]+)\[(.*)\]$/)
- next unless match
- resource_type, resource_name =
- match.captures.tap{|m| m[0] = m[0].to_sym}
- if notifies.xpath('descendant::string_embexpr').empty?
- next if resource_name.empty?
- else
- resource_name =
- notifies.xpath('args_add_block/args_add/string_literal')
- end
- else
- resource_type = params.xpath('symbol[1]/ident/@value').to_s.to_sym
- resource_name = params.xpath('string_add[1][count(../
- descendant::string_add) = 1]/tstring_content/@value').to_s
- resource_name = params if resource_name.empty?
- end
- {
- :type =>
- notifies.xpath('ident/@value[1]').to_s.to_sym,
- :resource_type => resource_type,
- :resource_name => resource_name,
- :style => params.empty? ? :new : :old,
- :action =>
- notifies.xpath('descendant::symbol[1]/ident/@value').to_s.to_sym,
- :timing =>
- if timing.empty?
- :delayed
- else
- case timing.first.to_s.to_sym
- when :immediately, :immediate then :immediate
- else timing.first.to_s.to_sym
- end
- end
- }
-
- end.compact
- end
-
# Does the provided string look like an Operating System command? This is a
# rough heuristic to be taken with a pinch of salt.
#
View
90 lib/foodcritic/notifications.rb
@@ -0,0 +1,90 @@
+module FoodCritic
+ module Notifications
+
+ # Decode resource notifications.
+ #
+ # @param [Nokogiri::XML::Node] ast The AST to check for notifications.
+ # @return [Array] A flat array of notifications. The resource_name may be
+ # a string or a Node if the resource name is an expression.
+ def notifications(ast)
+ return [] unless ast.respond_to?(:xpath)
+ notification_nodes(ast).map do |notify|
+ notified_resource = if new_style_notification?(notify)
+ new_style_notification(notify)
+ else
+ old_style_notification(notify)
+ end
+ next unless notified_resource
+ notified_resource.merge({
+ :type => notification_type(notify),
+ :style => new_style_notification?(notify) ? :new : :old,
+ :action => notification_action(notify),
+ :timing => notification_timing(notify)
+ })
+ end.compact
+ end
+
+ private
+
+ def new_style_notification(notify)
+ target = notify.xpath('args_add_block/args_add/
+ descendant::tstring_content/@value').to_s
+ match = target.match(/^([^\[]+)\[(.*)\]$/)
+ return nil unless match
+ resource_type, resource_name =
+ match.captures.tap{|m| m[0] = m[0].to_sym}
+ if notify.xpath('descendant::string_embexpr').empty?
+ return nil if resource_name.empty?
+ else
+ resource_name =
+ notify.xpath('args_add_block/args_add/string_literal')
+ end
+ {:resource_name => resource_name, :resource_type => resource_type}
+ end
+
+ def new_style_notification?(notify)
+ resource_hash_references(notify).empty?
+ end
+
+ def notification_action(notify)
+ notify.xpath('descendant::symbol[1]/ident/@value').to_s.to_sym
+ end
+
+ def notification_nodes(ast, &block)
+ ast.xpath('descendant::command[ident/@value="notifies" or
+ ident/@value="subscribes"]')
+ end
+
+ def notification_timing(notify)
+ timing = notify.xpath('args_add_block/args_add/symbol_literal[last()]/
+ symbol/ident[1]/@value')
+ if timing.empty?
+ :delayed
+ else
+ case timing.first.to_s.to_sym
+ when :immediately, :immediate then :immediate
+ else timing.first.to_s.to_sym
+ end
+ end
+ end
+
+ def notification_type(notify)
+ notify.xpath('ident/@value[1]').to_s.to_sym
+ end
+
+ def old_style_notification(notify)
+ resources = resource_hash_references(notify)
+ resource_type = resources.xpath('symbol[1]/ident/@value').to_s.to_sym
+ resource_name = resources.xpath('string_add[1][count(../
+ descendant::string_add) = 1]/tstring_content/@value').to_s
+ resource_name = resources if resource_name.empty?
+ {:resource_name => resource_name, :resource_type => resource_type}
+ end
+
+ def resource_hash_references(ast)
+ ast.xpath('descendant::method_add_arg[fcall/ident/
+ @value="resources"]/descendant::assoc_new')
+ end
+
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.