Refactored and moved Resource.create_dsl to ProfileContext.

ProfileContext#to_resources_dsl is the only usage of it.
The responsibility for this code should be on ProfileContext.

Refactored a majority of #create_dsl to be a 2-line long Module.new
instead of 36 lines. Much less magic. Still has an anonymous module
but it is now much easier to address and debug.

Signed-off-by: Ryan Davis <zenspider@chef.io>
This commit is contained in:
Ryan Davis 2020-01-06 17:14:19 -08:00
parent fa3122cbff
commit 89a0b44c64
3 changed files with 53 additions and 47 deletions

View file

@ -53,7 +53,7 @@ module Inspec
end
def to_resources_dsl
Inspec::Resource.create_dsl(self)
DomainSpecificLunacy.create_dsl(self)
end
def control_eval_context
@ -208,5 +208,55 @@ module Inspec
pid.to_s + "/" + rid.to_s
end
end
module DomainSpecificLunacy
def self.create_dsl(profile_context)
Module.new do
include DomainSpecificLunacy
add_methods(profile_context)
end
end
def self.included(mod)
mod.extend ClassMethods
end
def resource_class(profile_name, resource_name)
inner_context = if profile_name == profile_context.profile_id
profile_context
else
profile_context.subcontext_by_name(profile_name)
end
raise ProfileNotFound, "Cannot find profile named: #{profile_name}" if inner_context.nil?
inner_context.resource_registry[resource_name]
end
module ClassMethods
def add_methods(profile_context)
backend = profile_context.backend
define_method(:profile_context) { profile_context }
define_method(:inspec) { backend }
add_registry_methods(profile_context)
end
def add_registry_methods(profile_context)
be = profile_context.backend
bec = be.class
registry = profile_context.resource_registry
registry.each do |id, r|
define_method(id) { |*args| r.new(be, id.to_s, *args) }
next if be.respond_to?(id)
bec.define_method(id) { |*args| r.new(be, id.to_s, *args) }
end
end # add_resource_methods
end # ClassMethods
end # DomainSpecificLunacy
end # ProfileContext
end

View file

@ -185,50 +185,6 @@ module Inspec
end
end
# Creates the inner DSL which includes all resources for
# creating tests. It is always connected to one target,
# which is specified via the backend argument.
#
# @param backend [BackendRunner] exposing the target to resources
# @return [ResourcesDSL]
def self.create_dsl(profile_context)
backend = profile_context.backend
my_registry = profile_context.resource_registry
Module.new do
define_method :resource_class do |profile_name, resource_name|
inner_context = if profile_name == profile_context.profile_id
profile_context
else
profile_context.subcontext_by_name(profile_name)
end
raise ProfileNotFound, "Cannot find profile named: #{profile_name}" if inner_context.nil?
inner_context.resource_registry[resource_name]
end
my_registry.each do |id, r|
define_method id.to_sym do |*args|
r.new(backend, id.to_s, *args)
end
# confirm backend custom resources have access to other custom resources
next if backend.respond_to?(id)
backend.class.send(:define_method, id.to_sym) do |*args|
r.new(backend, id.to_s, *args)
end
end
# attach backend so we have access to all resources and
# the train connection object
define_method :inspec do
backend
end
end
end # create_dsl
def to_s
@__resource_name__
end

View file

@ -50,7 +50,7 @@ describe Inspec::ControlEvalContext do
end
describe "#resource_class" do
let(:resource_dsl) { Inspec::Resource.create_dsl(profile_context) }
let(:resource_dsl) { profile_context.to_resources_dsl }
let(:inner_context) { Inspec::ProfileContext.new("inner-context", backend, {}) }
let(:newfoo) { mock }
let(:control_content) do