lib/doorkeeper/config/option.rb
# frozen_string_literal: true module Doorkeeper class Config # Doorkeeper configuration option DSL module Option # Defines configuration option # # When you call option, it defines two methods. One method will take place # in the +Config+ class and the other method will take place in the # +Builder+ class. # # The +name+ parameter will set both builder method and config attribute. # If the +:as+ option is defined, the builder method will be the specified # option while the config attribute will be the +name+ parameter. # # If you want to introduce another level of config DSL you can # define +builder_class+ parameter. # Builder should take a block as the initializer parameter and respond to function +build+ # that returns the value of the config attribute. # # ==== Options # # * [:+as+] Set the builder method that goes inside +configure+ block # * [+:default+] The default value in case no option was set # * [+:builder_class+] Configuration option builder class # # ==== Examples # # option :name # option :name, as: :set_name # option :name, default: 'My Name' # option :scopes builder_class: ScopesBuilder # def option(name, options = {}) attribute = options[:as] || name attribute_builder = options[:builder_class] builder_class.instance_eval do if method_defined?(name) Kernel.warn "[DOORKEEPER] Option #{name} already defined and will be overridden" remove_method name end define_method name do |*args, &block| if (deprecation_opts = options[:deprecated]) warning = "[DOORKEEPER] #{name} has been deprecated and will soon be removed" warning = "#{warning}\n#{deprecation_opts.fetch(:message)}" if deprecation_opts.is_a?(Hash) Kernel.warn(warning) end value = if attribute_builder attribute_builder.new(&block).build else block || args.first end @config.instance_variable_set(:"@#{attribute}", value) end end define_method attribute do |*_args| if instance_variable_defined?(:"@#{attribute}") instance_variable_get(:"@#{attribute}") else options[:default] end end public attribute end def self.extended(base) return if base.respond_to?(:builder_class) raise Doorkeeper::MissingConfigurationBuilderClass, "Define `self.builder_class` method " \ "for #{base} that returns your custom Builder class to use options DSL!" end end end end