module RuboCop::Cop::EngineApi
Functionality for reading Rails Engine API declaration files.
Constants
- API_FILE_DETAILS
Public Instance Methods
engine_api_files_modified_time_checksum(engines_path)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 44 def engine_api_files_modified_time_checksum(engines_path) api_files = Dir.glob(File.join(engines_path, '**/app/api/**/api/**/*')) mtimes = api_files.sort.map { |f| File.mtime(f) } Digest::SHA1.hexdigest(mtimes.join) end
extract_api_list(engines_path, engine, api_file)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 27 def extract_api_list(engines_path, engine, api_file) key = cache_key(engine, api_file) @cache ||= {} cached = @cache[key] return cached if cached details = API_FILE_DETAILS[api_file] path = full_path(engines_path, engine, details) return [] unless File.file?(path) list = extract_array(path, details[:array_matcher]) @cache[key] = list list end
Private Instance Methods
api_path(engines_path, engine)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 60 def api_path(engines_path, engine) raw_name = ActiveSupport::Inflector.underscore(engine.to_s) File.join(engines_path, "#{raw_name}/app/api/#{raw_name}/api/") end
cache_key(engine, api_file)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 56 def cache_key(engine, api_file) "#{engine}-#{api_file}" end
extract_array(path, array_matcher)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 122 def extract_array(path, array_matcher) list = [] root_node = extract_module_root(path) root_node.children.each do |module_child| array_node = send(array_matcher, module_child) next if array_node.nil? array_node.children.map do |item| list << item.source end end list end
extract_module_root(path)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 70 def extract_module_root(path) # The AST for the whitelist definition looks like this: # # (:module, # (:const, # (:const, nil, :Trucking), :Api), # (:casgn, nil, :PUBLIC_SERVICES, # (:array, # (:const, # s(:const, nil, :Trucking), :CancelDeliveryOrderService), # (:const, # s(:const, nil, :Trucking), :FclFulfillmentDetailsService)) # # Or, in the case of two separate whitelists: # # (:module, # (:const, # (:const, nil, :Trucking), :Api), # s(:begin, # s(:casgn, nil, :PUBLIC_SERVICES, # s(:send, # s(:array, # s(:const, # s(:const, nil, :Trucking), :CancelDeliveryOrderService), # s(:const, # s(:const, nil, :Trucking), :ContainerUseService))), # s(:casgn, nil, :PUBLIC_CONSTANTS, # s(:send, # s(:array, # s(:const, # s(:const, nil, :Trucking), :DeliveryStatuses), # s(:const, # s(:const, nil, :Trucking), :LoadTypes)), :freeze))) # # We want the :begin in the 2nd case, the :module in the 1st case. module_node = parse_ast(File.read(path)) module_block_node = module_node&.children&.[](1) if module_block_node&.begin_type? module_block_node else module_node end end
full_path(engines_path, engine, details)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 52 def full_path(engines_path, engine, details) api_path(engines_path, engine) + details[:file_basename] end
parse_ast(source_code)
click to toggle source
# File lib/rubocop/cop/mixin/engine_api.rb, line 65 def parse_ast(source_code) source = RuboCop::ProcessedSource.new(source_code, RUBY_VERSION.to_f) source.ast end