diff --git a/Gemfile.lock b/Gemfile.lock index 79623493..4e825335 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,16 +1,16 @@ PATH remote: . specs: - resource_registry (0.7.0) + resource_registry (0.8.1) bootsnap (~> 1.0) deep_merge (>= 1.0.0) - dry-configurable (= 0.9) + dry-configurable (~> 0.11) dry-container (~> 0.7) dry-matcher (~> 0.7) dry-monads (~> 1.2) dry-struct (~> 1.0) dry-types (~> 1.0) - dry-validation (~> 1.2) + dry-validation (~> 1.6) i18n (>= 0.7.0) loofah (>= 2.3.1) mime-types @@ -42,7 +42,7 @@ GEM minitest (~> 5.1) tzinfo (~> 1.1) ast (2.4.0) - bootsnap (1.4.6) + bootsnap (1.5.1) msgpack (~> 1.0) bson (4.8.2) builder (3.2.4) @@ -54,18 +54,19 @@ GEM deep_merge (1.2.1) diff-lcs (1.3) docile (1.3.2) - dry-configurable (0.9.0) + dry-configurable (0.11.6) concurrent-ruby (~> 1.0) dry-core (~> 0.4, >= 0.4.7) + dry-equalizer (~> 0.2) dry-container (0.7.2) concurrent-ruby (~> 1.0) dry-configurable (~> 0.1, >= 0.1.3) - dry-core (0.4.9) + dry-core (0.4.10) concurrent-ruby (~> 1.0) dry-equalizer (0.3.0) dry-inflector (0.2.0) - dry-initializer (3.0.3) - dry-logic (1.0.6) + dry-initializer (3.0.4) + dry-logic (1.0.8) concurrent-ruby (~> 1.0) dry-core (~> 0.2) dry-equalizer (~> 0.2) @@ -75,7 +76,7 @@ GEM concurrent-ruby (~> 1.0) dry-core (~> 0.4, >= 0.4.4) dry-equalizer - dry-schema (1.5.0) + dry-schema (1.5.6) concurrent-ruby (~> 1.0) dry-configurable (~> 0.8, >= 0.8.3) dry-core (~> 0.4) @@ -95,13 +96,13 @@ GEM dry-equalizer (~> 0.3) dry-inflector (~> 0.1, >= 0.1.2) dry-logic (~> 1.0, >= 1.0.2) - dry-validation (1.5.0) + dry-validation (1.6.0) concurrent-ruby (~> 1.0) dry-container (~> 0.7, >= 0.7.1) dry-core (~> 0.4) dry-equalizer (~> 0.2) dry-initializer (~> 3.0) - dry-schema (~> 1.5) + dry-schema (~> 1.5, >= 1.5.2) erubi (1.9.0) i18n (1.8.2) concurrent-ruby (~> 1.0) @@ -113,7 +114,7 @@ GEM method_source (0.9.2) mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2020.0425) + mime-types-data (3.2020.1104) mini_portile2 (2.4.0) minitest (5.14.0) mongo (2.12.1) @@ -124,7 +125,7 @@ GEM msgpack (1.3.3) nokogiri (1.10.9) mini_portile2 (~> 2.4.0) - ox (2.13.2) + ox (2.13.4) parallel (1.19.1) parser (2.7.1.1) ast (~> 2.4.0) diff --git a/lib/resource_registry.rb b/lib/resource_registry.rb index 14763b88..4d3f1a95 100644 --- a/lib/resource_registry.rb +++ b/lib/resource_registry.rb @@ -20,6 +20,7 @@ require 'resource_registry/meta' require 'resource_registry/setting' require 'resource_registry/feature' +require 'resource_registry/setting_dsl' require 'resource_registry/feature_dsl' require 'resource_registry/configuration' require 'resource_registry/registry' diff --git a/lib/resource_registry/feature_dsl.rb b/lib/resource_registry/feature_dsl.rb index a3ea719b..6b7b693f 100644 --- a/lib/resource_registry/feature_dsl.rb +++ b/lib/resource_registry/feature_dsl.rb @@ -63,7 +63,9 @@ def setting(id) raise ArgumentError, "#{id} must be a String or Symbol" if !id.is_a?(String) && !id.is_a?(Symbol) id = id.to_sym - @feature.settings.detect { |setting| setting.key == id } + setting = @feature.settings.detect { |setting| setting.key == id } + return ResourceRegistry::SettingDSL.new(setting) if setting + setting end def label @@ -102,8 +104,21 @@ def display_order @feature.meta.order end + # registry[:feature_key] + # registry.resolve(:feature_key) def item - elements = @feature.item.to_s.split(/\./) + value = @feature.item + value = process_procs(value) + + if value.is_a?(Array) + elements = value.collect{|element| identify_feature(element) }.compact + return elements if elements.any? + end + + feature_value = identify_feature(value) + return feature_value if feature_value + + elements = value.to_s.split(/\./) if defined? Rails elements[0].constantize.send(elements[1]) @@ -113,5 +128,33 @@ def item rescue NameError @feature.item end + + def identify_feature(value) + if matched = value.to_s.match(/^registry\[(.*)\]$/) || matched = value.to_s.match(/^registry.resolve_feature\((.*)\)$/) + feature_key = matched[-1].gsub(':', '') + return registry[feature_key] + end + nil + end + + def process_procs(value) + if value.is_a?(Array) + value.collect{|element| process_procs(element) }.compact + elsif value.is_a?(Hash) + value.inject({}) {|data, (k, v)| data[k] = process_procs(v); data} + elsif value.is_a?(String) && value.match?(/Proc.new/) + eval(value).call + else + value + end + end + + def registry + return @registry if defined? @registry + + if defined? Rails + @registry = "#{Rails.application.class.module_parent_name}Registry".constantize + end + end end end diff --git a/lib/resource_registry/setting_dsl.rb b/lib/resource_registry/setting_dsl.rb new file mode 100644 index 00000000..823b4eb5 --- /dev/null +++ b/lib/resource_registry/setting_dsl.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require 'forwardable' + +module ResourceRegistry + # @api private + # Domain-Specific Language (DSL) for defining {ResourceRegistry::Setting} objects + class SettingDSL + extend Forwardable + + attr_reader :setting + + # @param [ResourceRegistry::Setting] setting Instance of a setting + # @yield the block to evaulate when calling the setting + # @return [Mixed] + def initialize(setting, &_block) + @setting = setting + end + + def key + @setting.key.to_s + end + + # @!method item + # The reference or code to be evaluated when setting is resolved + def_delegator :@setting, :item + + # @!method meta + def_delegator :@setting, :meta + + def label + @setting.meta.label + end + + def default_value + @setting.meta.default + end + + def value + @setting.meta.value + end + + def type + @setting.meta.type + end + + def enumerations + @setting.meta.enum + end + + def description + @setting.meta.description + end + + def required? + @setting.meta.is_required + end + + def visible? + @setting.meta.is_visible + end + + def display_order + @setting.meta.order + end + + # registry[:feature_key] + # registry.resolve(:feature_key) + def item + value = @setting.item + value = process_procs(value) + + if value.is_a?(Array) + elements = value.collect{|element| identify_feature(element) }.compact + return elements if elements.any? + end + + feature_value = identify_feature(value) + return feature_value if feature_value + + return value unless value.is_a?(String) + elements = value.split(/\./) + + if defined? Rails + elements[0].constantize.send(elements[1]) + else + Module.const_get(elements[0]).send(elements[1]) + end + rescue NameError + @setting.item + end + + def identify_feature(value) + if matched = value.to_s.match(/^registry\[(.*)\]$/) || matched = value.to_s.match(/^registry.resolve_feature\((.*)\)$/) + feature_key = matched[-1].gsub(':', '') + return registry[feature_key] + end + + nil + end + + def process_procs(value) + if value.is_a?(Array) + value.collect{|element| process_procs(element) }.compact + elsif value.is_a?(Hash) + value.inject({}) {|data, (k, v)| data[k] = process_procs(v); data} + elsif value.is_a?(String) && value.match?(/Proc.new/) + eval(value).call + else + value + end + end + + def registry + return @registry if defined? @registry + + if defined? Rails + @registry = "#{Rails.application.class.module_parent_name}Registry".constantize + end + end + end +end diff --git a/lib/resource_registry/version.rb b/lib/resource_registry/version.rb index f7ef834e..968e5482 100644 --- a/lib/resource_registry/version.rb +++ b/lib/resource_registry/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ResourceRegistry - VERSION = "0.7.0" + VERSION = "0.8.1" end diff --git a/resource_registry.gemspec b/resource_registry.gemspec index 516d8814..baf5f37c 100644 --- a/resource_registry.gemspec +++ b/resource_registry.gemspec @@ -32,10 +32,10 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.5.1' - spec.add_dependency 'dry-validation', '~> 1.2' + spec.add_dependency 'dry-validation', '~> 1.6' spec.add_dependency 'dry-struct', '~> 1.0' spec.add_dependency 'dry-types', '~> 1.0' - spec.add_dependency 'dry-configurable', '0.9' + spec.add_dependency 'dry-configurable', '~> 0.11' spec.add_dependency 'dry-container', '~> 0.7' spec.add_dependency 'deep_merge', '>= 1.0.0' diff --git a/spec/resource_registry/feature_dsl_spec.rb b/spec/resource_registry/feature_dsl_spec.rb index 7e35c7c7..0800b309 100644 --- a/spec/resource_registry/feature_dsl_spec.rb +++ b/spec/resource_registry/feature_dsl_spec.rb @@ -105,7 +105,7 @@ def call(params) let(:first_setting_id) { first_setting.key } it "correctly returns an individual setting for a feature" do - expect(dsl.setting(first_setting_id)).to eq first_setting + expect(dsl.setting(first_setting_id).setting).to eq first_setting end it "returns nil if named setting isn't found" do