Class: YiffSpace::ConfigBuilder

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/yiffspace/config_builder.rb

Defined Under Namespace

Classes: SubconfigProxy

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.config(name, type = :string, env: true, required: false, blank: false, &block) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/yiffspace/config_builder.rb', line 16

def self.config(name, type = :string, env: true, required: false, blank: false, &block)
  name = name.to_sym
  remove_config(name) if list.include?(name)
  list << name
  self.required << name if required
  if block.nil?
    unset << name
    block = -> { raise(NotImplementedError, "Config option #{name} is not set") }
  end
  define_method(name) do |*args|
    env_or_value(name, args, blank: blank, &block)
  end
  if type == :boolean
    define_method("#{name}?") do |*args|
      public_send(name, *args)
    end
  end
  reviver(name, type) if type && type != :string
  env_set[name] = env
end

.ensure_required_set!Object



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/yiffspace/config_builder.rb', line 131

def self.ensure_required_set!
  unset = []
  required.each do |name|
    value = begin
      instance.public_send(name)
    rescue StandardError
      nil
    end
    unset << name if value.blank?
  end

  raise("Missing required configuration options: #{unset.join(', ')}") if unset.any?
end

.remove_config(name, reviver: false) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/yiffspace/config_builder.rb', line 37

def self.remove_config(name, reviver: false)
  name = name.to_sym
  list.delete(name)
  required.delete(name)
  unset.delete(name)
  reviver_map.delete(name) if reviver
  env_set.delete(name)
  remove_method(name)
  remove_method("#{name}?") if method_defined?("#{name}?")
end

.reviver(name, type = nil, &block) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/yiffspace/config_builder.rb', line 63

def self.reviver(name, type = nil, &block)
  if block
    reviver_map[name] = block
    return
  end
  method            = case type
                      when :boolean
                        ->(v) { !v.match?(/\A(false|f|no|n|off|0)\z/i) }
                      when :integer
                        ->(v) { v.to_i }
                      when :symbol
                        ->(v) { v.to_sym }
                      when :array
                        ->(v) { v.split(/\s*,\s*/) }
                      else
                        raise(ArgumentError, "not sure how to revive #{type} for #{method}")
                      end
  reviver_map[name] = method
end

.subconfig(prefix, parent: [], &block) ⇒ Object

Raises:

  • (ArgumentError)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/yiffspace/config_builder.rb', line 83

def self.subconfig(prefix, parent: [], &block)
  raise(ArgumentError, "block required") unless block

  prefix = prefix.to_sym
  path   = parent + [prefix]

  node = subconfigs
  path.each do |p|
    node[p] ||= {}
    node    = node[p]
  end

  define_method(prefix) { SubconfigProxy.new(self, path) } unless method_defined?(prefix)

  collector = Module.new do
    def self.collected
      @collected ||= []
    end

    def self.config(name, type = :string, env: true, required: false, blank: false, &block)
      collected << [:config, name, type, env, required, blank, block]
    end

    def self.reviver(name, type = nil, &block)
      collected << [:reviver, name, type, block]
    end

    def self.subconfig(name, &block)
      collected << [:subconfig, name, block]
    end
  end

  collector.module_eval(&block)

  collector.collected.each do |kind, name, *args|
    case kind
    when :config
      full = (path + [name]).join("_").to_sym
      config(full, args[0], env: args[1], required: args[2], blank: args[3], &args[4])
    when :reviver
      full = (path + [name]).join("_").to_sym
      reviver(full, args[0], &args[1])
    when :subconfig
      subconfig(name, parent: path, &args[0])
    end
  end
end

Instance Method Details

#env(name) ⇒ Object



59
60
61
# File 'lib/yiffspace/config_builder.rb', line 59

def env(name)
  ENV.fetch("#{self.class.env_name}_#{name.to_s.upcase}", nil)
end

#env_or_value(name, args, blank: false) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/yiffspace/config_builder.rb', line 48

def env_or_value(name, args, blank: false, &)
  value = env(name)
  value = nil if !value.nil? && value.blank? && !blank
  if value.nil?
    instance_exec(*args, &)
  else
    reviver = reviver_map.fetch(name, proc(&:itself))
    instance_exec(value, *args, &reviver)
  end
end

#present?(*names) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/yiffspace/config_builder.rb', line 145

def present?(*names)
  names.flatten.all? { |name| public_send(name).present? }
end